pyyaml加载数为十进制

jsh*_*arp 5 python yaml pyyaml

yaml.load在Python浮动时加载数字。我找不到一种简单的方法来替代此方法。

Compare json.load,它允许parse_float=Decimal您是否要将浮点数解析为decimal.Decimals。

有什么办法可以用PyYAML做到这一点?还是不建议使用YAML规范的某些属性?

fly*_*lyx 6

您可以执行以下操作:

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

yaml.add_constructor(u'!decimal', decimal_constructor)
Run Code Online (Sandbox Code Playgroud)

这使您可以加载小数,但只有当它们与前缀!decimal的YAML文档中的标签。但是,您可以使用自定义方式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.'))
Run Code Online (Sandbox Code Playgroud)

您应该从默认解析器复制其他隐式解析器。然后,您需要定义一个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)
Run Code Online (Sandbox Code Playgroud)

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

yaml.add_constructor(u'!decimal', decimal_constructor, MyLoader)
Run Code Online (Sandbox Code Playgroud)

最后,使用加载YAML

yaml.load(stream, MyLoader)
Run Code Online (Sandbox Code Playgroud)

  • 有用!谢谢!概念的工作证明:https://gist.github.com/jpassaro/4d5812290cdca51a8d3fe03c499d4149 (2认同)