Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用pyyaml生成具有覆盖的yaml锚/引用_Python_Yaml_Pyyaml - Fatal编程技术网

Python 使用pyyaml生成具有覆盖的yaml锚/引用

Python 使用pyyaml生成具有覆盖的yaml锚/引用,python,yaml,pyyaml,Python,Yaml,Pyyaml,使用人工编写的YAML可以做到以下几点: foo: &foo_anchor key1: v1 key2: v2 key3: v3 bar: <<: *foo_anchor key2: override_value 弄乱了预期的事件流。这可能吗?你可以这样做: import yaml class Merger(object): pass def merger_representer(dumper, data): return dumper.re

使用人工编写的YAML可以做到以下几点:

foo: &foo_anchor
  key1: v1
  key2: v2
  key3: v3
bar:
  <<: *foo_anchor
  key2: override_value

弄乱了预期的事件流。这可能吗?

你可以这样做:

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。您无法控制生成的锚名称,但此YAML与您的相当


您需要merge类来强制PyYAML发出,实现这一点的一种方法是创建一个包含适当 有关合并信息的信息,并且仍然允许查找 数据['bar']['key1']。当然,您需要使用适当的representer正确地转储这个类

这是ruamel.yaml的免责声明,我是 该软件包的作者不允许合并地图的往返:

import sys
import ruamel.yaml

yaml_str = """\
foo: &foo_anchor
  key1: v1
  key2: v2
  key3: v3
bar:
  <<: *foo_anchor
  key2: override_value
"""

yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
从零开始,它提供了与您期望的类似的东西:

foo: &foo_anchor
  key1: v1
  key2: v2
  key3: v3
bar:
  <<: *foo_anchor
  key2: override_value
给予:

['key2', 'key1', 'key3']
v3

在PyYAML>=5.1中,您实际上可以使用yaml.dump…,sort_keys=False。如果python版本实现了itI,那么这将转储原始的键顺序。最终,通过直接操作CommentedMap,我知道了如何做到这一点。但是,这个答案没有帮助,因为我不关心往返:我不是从yaml开始的,我是通过编程生成它的。看起来您只阅读了我答案的一半,因为第二部分是通过编程生成输出的。我以往返开始我的回答是为了表明它足以以编程方式创建正确的结构,以及它应该是什么样子。但如果你阅读有困难,难怪花了这么长时间才让它起作用。
foo: &foo_anchor
  key1: v1
  key2: v2
  key3: v3
bar:
  <<: *foo_anchor
  key2: override_value
print(list(data['bar'].keys()))
print(data['bar']['key3'])
['key2', 'key1', 'key3']
v3