有什么方法可以覆盖 pyyaml 对布尔值的自由处理吗?
Is there any way to override pyyaml's liberal handling of boolean values?
看起来 pyyaml 实现了 YAML 1.1 spec 的一部分,它允许将许多不同的值解释为真或假:
规范:
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
但它会将它们序列化为 true
或 false
(与 YAML 1.1 的规范 y
和 n
形成对比):
>>> yaml.safe_dump(dict(x=True, y=False))
'{x: true, y: false}\n'
是否有任何方法可以覆盖它,以便只有规范的 true
和 false
值被解释为布尔值?
您应该执行以下操作以使 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
subclass,它可以完成 Resolver
所做的一切,但没有如上所述的 2002:bool
定义,而是受限制的 (1.2) 版本.
更新 constructor.py
中 SafeConstructor
的 bool_values
class 属性
这并不能使 PyYAML 1.2 兼容,因为还有更多,PyYAML 并没有完全实现 YAML 1.1 规范。
将 YAML 加载到 python 并且不将 Yes 解释为布尔值的最简单方法是使用 ruamel.yaml 而不是 PyYAML(免责声明:我是该包的作者)。如果文件被标记为 YAML 1.1(如果没有标记 ruamel.yaml 假定版本 1.2),您还可以在其源代码中找到如何保持解析器 1.1 兼容。
看起来 pyyaml 实现了 YAML 1.1 spec 的一部分,它允许将许多不同的值解释为真或假:
规范:
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
但它会将它们序列化为 true
或 false
(与 YAML 1.1 的规范 y
和 n
形成对比):
>>> yaml.safe_dump(dict(x=True, y=False))
'{x: true, y: false}\n'
是否有任何方法可以覆盖它,以便只有规范的 true
和 false
值被解释为布尔值?
您应该执行以下操作以使 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
subclass,它可以完成Resolver
所做的一切,但没有如上所述的2002:bool
定义,而是受限制的 (1.2) 版本.更新
constructor.py
中SafeConstructor
的bool_values
class 属性
这并不能使 PyYAML 1.2 兼容,因为还有更多,PyYAML 并没有完全实现 YAML 1.1 规范。
将 YAML 加载到 python 并且不将 Yes 解释为布尔值的最简单方法是使用 ruamel.yaml 而不是 PyYAML(免责声明:我是该包的作者)。如果文件被标记为 YAML 1.1(如果没有标记 ruamel.yaml 假定版本 1.2),您还可以在其源代码中找到如何保持解析器 1.1 兼容。