YAML中任何以百分号结尾的数字序列都将
通常作为字符串标量加载,因为%不会
标量匹配任何其他模式(尤其是不匹配整数的模式
或浮动)。当然,您可以递归地遍历数据结构
从YAML和patch加载,但是如果在
数据结构,用于构造特定对象,递归到这些对象中
至少是不平凡的,如果不是不可能的话。在
最好的解决方案是你的YAML将
通过标签说明百分比。E、 g.:a: !Percentage 60%
,其中从该标记加载的对象的行为类似于float
0.6。但标签在使用YAML时使用不足,而你没有
指示您的输入以这种方式标记。在
幸运的是,为百分比设置一个解析器并不太困难
在一个加载程序中,下面我将为默认的RoundTripLoader执行此操作。在
要解析的YAML文档in.yaml:
^{pr2}$
您可以钩住resenter来检查字符串是否由数字组成
以百分号结尾,但添加解析程序更快:import sys
import re
from pathlib import Path
import ruamel.yaml
from ruamel.yaml.util import RegExp
ruamel.yaml.resolver.VersionedResolver.add_implicit_resolver(
u'percentage',
RegExp(u'''^(?:[-+]?[0-9_]+%
|[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?%
)$''', re.X
),
list(u'-+0123456789.'))
def construct_percentage(self, node):
value = float(node.value[:-1]) / 100.0
return value
ruamel.yaml.constructor.RoundTripConstructor.add_constructor(
u'percentage', construct_percentage
)
yaml = ruamel.yaml.YAML()
data = yaml.load(Path('in.yaml'))
print(dict(data))
它给出了:{'a': 0.603, 0.42: 'abc'}
请注意:默认情况下,数据加载在ordereddict的子类中,因此调用dict()。在
如果您还想转储百分比,您应该将它们作为float的子类加载,
所以当你要倾倒它们的时候,它们和普通的漂浮物是不同的。在
我故意省略了ints的其他格式(十六进制、八进制等)和
浮点数(科学记数法、NaN等)。在我看来,他们没有多大意义,但他们
可以通过模式匹配器重新允许。在