加载包含不同嵌套级别的锚点的文件时,锚点似乎丢失了,并且密钥保持为空。
加载以下文件时:
---
Dict1:
- InnerDict: &inner
key: val
Dict2:
InnerDict:
<<: *inner
Dict3:
- InnerDict:
<<: *inner
...
...包含代码(Python 3.7,ruamel.yaml版本0.15.78):
from ruamel.yaml import YAML
with open("file.yaml") as infile:
content = YAML(typ='rt', pure=True).load(infile)
print(content)
...给出:
{'Dict1': [ordereddict([('InnerDict', ordereddict([('key', 'val')]))])],
'Dict2': ordereddict([('InnerDict', ordereddict())]),
'Dict3': [ordereddict([('InnerDict', ordereddict([('key', 'val')]))])]}
... Dict2
的内部字典为空。
在安全模式下,两种情况下的锚都将按预期方式解释。
它是故意的还是一个错误?
答案 0 :(得分:0)
那绝对是一个错误,这与广度优先有关
在数据结构中构建映射。到时候
InnerDict
下的Dict2
被构造,其中一个嵌套在Dict1
下
不完全可用。 InnerDict
下的Dict3
位于
相同的深度,因此可以正确构造(
如果您删除Dict1
结构中的破折号,请先合并
使锚点出现在较浅的位置)。
除了安装ruamel.yaml>=0.15.79
外,解决此问题的一种方法是
提供替代的构造函数,该结构强制进行深度优先处理:
import sys
import ruamel.yaml
class MyConstructor(ruamel.yaml.constructor.RoundTripConstructor):
def construct_yaml_map(self, node):
data = ruamel.yaml.comments.CommentedMap()
data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
yield data
self.construct_mapping(node, data, deep=True)
self.set_collection_style(data, node)
MyConstructor.add_constructor(
u'tag:yaml.org,2002:map', MyConstructor.construct_yaml_map
)
yaml = ruamel.yaml.YAML()
yaml.Constructor = MyConstructor
yaml_str = """\
Dict1:
- InnerDict: &inner
key: val
Dict2:
InnerDict:
<<: *inner
Dict3:
- InnerDict:
<<: *inner
"""
data = yaml.load(yaml_str)
for k in data:
print(k, data[k])
print('---------')
yaml.dump(data, sys.stdout)
正在生成:
Dict1 [ordereddict([('InnerDict', ordereddict([('key', 'val')]))])]
Dict2 ordereddict([('InnerDict', ordereddict([('key', 'val')]))])
Dict3 [ordereddict([('InnerDict', ordereddict([('key', 'val')]))])]
---------
Dict1:
- InnerDict: &inner
key: val
Dict2:
InnerDict:
<<: *inner
Dict3:
- InnerDict:
<<: *inner
(由于data
的转储是正确的,即使没有上述“补丁”,此
测试往返时以前未检测到