簡體   English   中英

如何使用ruamel.yaml自動添加參考?

[英]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來自任何地方...

這里有幾個問題:

  • 如果您期望鍵foobar出現在輸出中,則必須在源代碼中的某個地方指定它們。

  • 如果您希望自己的YAML文檔是隱式的(即,不是以---開頭),則不應指定explicit_start=True

  • 沒有鍵被轉儲為? 不如~

  • 如果使用update()dict填充CommentedMap() (即有序詞典),則不能期望鍵會以特定順序添加。 如果要按acb順序(如您所指出的那樣),則必須確保這是將它們呈現給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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM