前段时间我问了一个非常相似的question,但我仍然对如何在YAML转储上添加引用感到困惑。
我的目标是在默认值上添加锚点,以最大限度地减少转储上的冗余。所以我写了这个:
import collections
import ruamel.yaml as yaml
default = {'a': 1, 'b': 2, 'c': 3}
data = {
(1,2,3,4): {1: {'a': 10}, 2: {'b': 20}},
(5,6,7,8): {1: {}, 2: {'a': 100, 'b': 200, 'c': 300}},
}
d = yaml.comments.CommentedMap()
d.update(default)
d.yaml_set_anchor('default')
default = d
for m, a in data.items():
for k in a.keys():
u = yaml.comments.CommentedMap()
u.update(a[k])
u.add_yaml_merge([(0, default)])
a[k] = u
data[None] = default
def my_key_repr(self, data):
if isinstance(data, tuple):
return self.represent_sequence(u'tag:yaml.org,2002:seq', data, flow_style=True)
return yaml.representer.SafeRepresenter.represent_key(self, data)
yaml.representer.RoundTripRepresenter.represent_key = my_key_repr
print yaml.dump(data, Dumper=yaml.RoundTripDumper, width=100, allow_unicode=True,
explicit_start=True)
预期输出为:
---
~: &default
a: 1
c: 3
b: 2
[1, 2, 3, 4]:
1:
<<: *default
a: 10
2:
<<: *default
b: 20
[5, 6, 7, 8]:
1:
<<: *default
2:
<<: *default
a: 100
c: 300
b: 200
我得到的是:
---
?
: &default
a: 1
c: 3
b: 2
[1, 2, 3, 4]:
1:
<<: *default
a: 10
2:
<<: *default
b: 20
&id001 [5, 6, 7, 8]:
1:
<<: *id001
2:
<<: *id001
a: 100
c: 300
b: 200
*id001
来自无处......
答案 0 :(得分:1)
这里有几个问题:
如果您希望按键foo
和bar
显示在输出中,则必须在源代码中指定它们。
如果您希望YAML文档是隐式的(即不是以---
开头),那么您不应指定explicit_start=True
无关键被转储为?
而不是~
如果您使用update()
从CommentedMap()
填充dict
(即有序字典),则无法期望按特定顺序添加密钥。如果您想按顺序a
,c
,b
(如您所示),您必须确保这是按照{{1} {1}}
由于您的顶级CommentedMap()
未订购,因此无法保证您的YAML文档中的顶层映射是data
密钥(null
或? :
)。
以下内容:
~:
准确地给出了您期望的输出。