您可以使用人工编写的 YAML 执行以下操作:
foo: &foo_anchor
key1: v1
key2: v2
key3: v3
bar:
<<: *foo_anchor
key2: override_value
我想使用 PyYAML 以编程方式生成类似的输出。看起来很棘手!默认情况下,据我所知,PyYAML 仅在遇到相同对象时生成 anchor /引用(并且顺序可能未定义,而在本示例中, bar
必须引用 foo
,而不是相反)。我尝试了一些方法 - 定义一个 YamlReference
类并在重写的 Dumper.serialize_node
方法中检查其标记 - 但尝试执行以下操作:
if node.tag.endswith('magic.prefix.YamlReference'):
alias = node.value[0].value
self.emit(yaml.events.AliasEvent(alias))
super(Dumper, self).anchor_node(node.value[1])
super(Dumper, self).serialize_node(node.value[1], parent, idx)
打乱了预期的事件流。这可能吗?
最佳答案
你可以这样做:
import yaml
class Merger(object):
pass
def merger_representer(dumper, data):
return dumper.represent_scalar(u'tag:yaml.org,2002:merge', '<<')
yaml.add_representer(Merger, merger_representer)
foo = {'key1': 'v1', 'key2': 'v2', 'key3': 'v3'}
root = {
'foo': foo,
'bar': {
Merger(): foo,
'key2': 'override_value'
}
}
print(yaml.dump(root, sort_keys=False))
输出是:
foo: &id001
key1: v1
key2: v2
key3: v3
bar:
<<: *id001
key2: override_value
sort_keys=False
确保键的正确顺序,它需要 Python >= 3.7 和 PyYAML >= 5.1 (感谢@tinita)。您无法控制生成的 anchor 名称,但此 YAML 与您的相同。
您需要 Merger
强制 PyYAML 发出的类 <<
(使用普通的字符串键,它会发出 '<<'
这样就不会与合并键混淆)。
关于python - 使用 pyyaml 生成带有覆盖的 yaml anchor /引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59307826/