pyyaml加载数为十进制

时间:2017-11-16 22:37:58

标签: python yaml pyyaml

yaml.load加载数字作为Python浮点数。我无法找到一种直接的方式来覆盖它。

比较json.load,如果要将浮点数解析为parse_float=Decimal,则允许decimal.Decimal

有没有办法用PyYAML来实现这个目标?或者YAML规范的某些属性是不可取的?

1 个答案:

答案 0 :(得分:3)

您可以执行以下操作:

def decimal_constructor(loader, node):
    value = loader.construct_scalar(node)
    return Decimal(value)

yaml.add_constructor(u'!decimal', decimal_constructor)

这允许您加载小数,但如果它们以YAML文档中的!decimal标记为前缀,则仅 。但是,您可以使用自定义Resolver将所有数字解析为!decimal

class MyResolver(BaseResolver):
    pass

MyResolver.add_implicit_resolver(
        '!decimal',
        re.compile(r'''^(?:[-+]?(?:[0-9][0-9_]*)\.[0-9_]*(?:[eE][-+][0-9]+)?
                    |\.[0-9_]+(?:[eE][-+][0-9]+)?
                    |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*
                    |[-+]?\.(?:inf|Inf|INF)
                    |\.(?:nan|NaN|NAN))$''', re.X),
        list('-+0123456789.'))

您应该从default resolver复制其他隐式解析器。然后,您需要定义一个使用解析器的Loader

class MyLoader(Reader, Scanner, Parser, Composer, SafeConstructor, MyResolver):
    def __init__(self, stream):
        Reader.__init__(self, stream)
        Scanner.__init__(self)
        Parser.__init__(self)
        Composer.__init__(self)
        SafeConstructor.__init__(self)
        MyResolver.__init__(self)

上面,我们将构造函数添加到默认加载器中。将该行更改为:

yaml.add_constructor(u'!decimal', decimal_constructor, MyLoader)

最后,使用

加载YAML
yaml.load(stream, MyLoader)