now*_*wox 5 python yaml pyyaml ruamel.yaml
递归引用在ruamel.yaml或中可以很好地工作pyyaml:
$ ruamel.yaml.dump(ruamel.yaml.load('&A [ *A ]'))
'&id001
- *id001'
Run Code Online (Sandbox Code Playgroud)
但是(显然)它不适用于普通引用:
$ ruamel.yaml.dump(ruamel.yaml.load("foo: &foo { a: 42 }\nbar: { <<: *foo }"))
bar: {a: 42}
foo: {a: 42}
Run Code Online (Sandbox Code Playgroud)
我想显式创建一个引用:
data = {}
data['foo'] = {'foo': {'a': 42}}
data['bar'] = { '<<': data['foo'], 'b': 43 }
$ ruamel.yaml.dump(data, magic=True)
foo: &foo
a: 42
bar:
<<: *foo
b: 43
Run Code Online (Sandbox Code Playgroud)
这对于生成具有大量公共密钥的大型数据结构的YAML输出非常有用。
没有争议的输出替换怎么办?
其实的结果ruamel.yaml.dump(data)是
bar:
'<<': &id001
foo:
a: 42
b: 43
foo: *id001
Run Code Online (Sandbox Code Playgroud)
所以,我需要更换'<<'有<<,也许替换id001用foo。
如果您想创建类似的内容,至少在 ruamel.yaml \xc2\xb9 中,您应该使用往返模式,这也会保留合并。以下不会引发断言错误:
\n\nimport ruamel.yaml\n\nyaml_str = """\\\nfoo: &xyz\n a: 42\nbar:\n <<: *xyz\n"""\n\ndata = ruamel.yaml.round_trip_load(yaml_str)\nassert ruamel.yaml.round_trip_dump(data) == yaml_str\nRun Code Online (Sandbox Code Playgroud)\n\n这意味着data有足够的信息来重新创建输出中的合并。然而实际上,在往返模式下,合并永远不会发生。相反,检索一个值意味着其中data[\'foo\'][\'bar\'][\'a\']没有真正的键\'bar\'data[\'foo\'],但随后会在附加的“合并映射”中查找该键。
没有为此的公共接口(所以事情可能会改变),但是通过分析data和查看ruamel.yaml.comments.CommentedMap()你可以发现有一个merge_attrib(当前是 string _yaml_merge)并且更有用的是有一个方法add_yaml_merge()。后者采用 (int, CommentedMap()) 元组列表。
baz = ruamel.yaml.comments.CommentedMap()\nbaz[\'b\'] = 196\nbaz.yaml_set_anchor(\'klm\')\ndata.insert(1, \'baz\', baz)\nRun Code Online (Sandbox Code Playgroud)\n\n需要将\'baz\'key插入到data的key之前\'bar\',否则映射会反转。在合并中插入新结构后data[\'bar\']:
data[\'bar\'].add_yaml_merge([(0, baz)])\nruamel.yaml.round_trip_dump(data, sys.stdout)\nRun Code Online (Sandbox Code Playgroud)\n\n这使:
\n\nfoo: &xyz\n a: 42\nbaz: &klm\n b: 196\nbar:\n <<: [*xyz, *klm]\nRun Code Online (Sandbox Code Playgroud)\n\n(如果你想看什么add_yaml_merge插入了什么
print(getattr(data[\'bar\'], ruamel.yaml.comments.merge_attrib))\nRun Code Online (Sandbox Code Playgroud)\n\n通话前和通话后)
\n\n如果你想完全从头开始,你可以这样做:
\n\ndata = ruamel.yaml.comments.CommentedMap([\n (\'foo\', ruamel.yaml.comments.CommentedMap([(\'a\', 42)])),\n ])\ndata[\'foo\'].yaml_set_anchor(\'xyz\')\ndata[\'bar\'] = bar = ruamel.yaml.comments.CommentedMap()\nbar.add_yaml_merge([(0, data[\'foo\'])])\nRun Code Online (Sandbox Code Playgroud)\n\n而不是data = ruamel.yaml.round_trip_load(yaml_str).
\xc2\xb9免责声明:我是该包的作者。
\n| 归档时间: |
|
| 查看次数: |
739 次 |
| 最近记录: |