有没有办法覆盖pyyaml对布尔值的自由处理?

时间:2017-02-16 20:40:01

标签: python yaml pyyaml

看起来pyyaml实现了YAML 1.1 spec的一部分,它允许将许多不同的值解释为true或false:

典型:

y|n

正则表达式:

y|Y|yes|Yes|YES|n|N|no|No|NO
 |true|True|TRUE|false|False|FALSE
 |on|On|ON|off|Off|OFF`
>>> for k in "y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF".split("|"):
...   print k, yaml.safe_load(k)
...
y y
Y Y
yes True
Yes True
YES True
n n
N N
no False
No False
NO False
true True
True True
TRUE True
false False
False False
FALSE False
on True
On True
ON True
off False
Off False
OFF False

但它将它们序列化为truefalse(与YAML 1.1的规范yn相反):

>>> yaml.safe_dump(dict(x=True, y=False))
'{x: true, y: false}\n'

有没有办法覆盖它,只有规范的truefalse值被解释为布尔值?

1 个答案:

答案 0 :(得分:1)

您应该执行以下操作以使PyYAML不将这些字符串识别为布尔值:

  • 替换resolver.py中添加的添加的隐式解析程序,默认情况下为:

    Resolver.add_implicit_resolver(
            u'tag:yaml.org,2002:bool',
            re.compile(ur'''^(?:yes|Yes|YES|no|No|NO
                        |true|True|TRUE|false|False|FALSE
                        |on|On|ON|off|Off|OFF)$''', re.X),
            list(u'yYnNtTfFoO'))
    

    您必须跟踪add_implicit_resolver以查看它添加的内容,因为没有remove_implicit_resolver。或者,定义一个完整的新ResolverBase子类,它完成Resolver所做的一切,但不具有上述2002:bool的定义,但是受限制的(1.2)版本。

  • 更新bool_values

  • SafeConstructor的{​​{1}}类属性

这不会使PyYAML 1.2兼容,因为还有更多内容,PyYAML并没有完全实现YAML 1.1规范。

将YAML加载到python中并且没有Yes被解释为布尔值的最简单方法是使用ruamel.yaml而不是PyYAML(免责声明:我是该软件包的作者)。在其源代码中,您还可以找到如果文件被标记为YAML 1.1,如何保持解析器1.1兼容(如果没有标记ruamel.yaml假定版本1.2)。