加载包含不同嵌套级别的锚点的文件时,锚点似乎丢失了,并且键保持为空。

加载以下文件时:

---
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的内部字典保留为空。

在安全模式下,两种情况下的锚都将按预期进行解释。

它是故意的还是一个错误?

最佳答案

那绝对是一个错误,它与广度优先有关
在数据结构中构建映射。到时候
构造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的转储是正确的,即使没有上述“补丁”,此
测试往返时以前未检测到)

07-24 09:46