[英]How to automatically add a reference with ruamel.yaml?
不久前我問了一個非常類似的問題 ,但是我仍然對如何在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
來自任何地方...
這里有幾個問題:
如果您期望鍵foo
和bar
出現在輸出中,則必須在源代碼中的某個地方指定它們。
如果您希望自己的YAML文檔是隱式的(即,不是以---
開頭),則不應指定explicit_start=True
沒有鍵被轉儲為?
不如~
如果使用update()
從dict
填充CommentedMap()
(即有序詞典),則不能期望鍵會以特定順序添加。 如果要按a
, c
, b
順序(如您所指出的那樣),則必須確保這是將它們呈現給CommentedMap()
的順序。
由於頂級data
未排序,因此不能保證在YAML文檔中頂級映射為null
鍵( ? :
或~:
:)。
下列:
from ruamel import yaml
d = {'a': 1, 'b': 2, 'c': 3}
abc = yaml.comments.CommentedMap()
abc['a'] = 100
abc['c'] = 300
abc['b'] = 200
base = [
('foo', {1: {'a': 10}, 2: {'b': 20}}),
('bar', {1: {}, 2: abc}),
]
data = yaml.comments.CommentedMap()
default = yaml.comments.CommentedMap()
for m, a in base:
data[m] = a
for k in sorted(d):
default[k] = d[k]
default.yaml_set_anchor('default')
for m, a in data.items():
for k in sorted(a.keys()):
u = yaml.comments.CommentedMap()
u.update(a[k])
u.add_yaml_merge([(0, default)])
a[k] = u
data.insert(0, None, default)
x = yaml.round_trip_dump(data, width=100).replace('?\n:', '~:')
print(x)
准確給出您期望的輸出。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.