python - 使用 pyyaml 生成带有覆盖的 yaml anchor /引用

标签 python yaml pyyaml

您可以使用人工编写的 YAML 执行以下操作:

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

我想使用 PyYAML 以编程方式生成类似的输出。看起来很棘手!默认情况下,据我所知,PyYAML 仅在遇到相同对象时生成 anchor /引用(并且顺序可能未定义,而在本示例中, bar 必须引用 foo ,而不是相反)。我尝试了一些方法 - 定义一个 YamlReference 类并在重写的 Dumper.serialize_node 方法中检查其标记 - 但尝试执行以下操作:

        if node.tag.endswith('magic.prefix.YamlReference'):
            alias = node.value[0].value
            self.emit(yaml.events.AliasEvent(alias))
            super(Dumper, self).anchor_node(node.value[1])
            super(Dumper, self).serialize_node(node.value[1], parent, idx)

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

最佳答案

你可以这样做:

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

您需要 Merger强制 PyYAML 发出的类 << (使用普通的字符串键,它会发出 '<<' 这样就不会与合并键混淆)。

关于python - 使用 pyyaml 生成带有覆盖的 yaml anchor /引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59307826/

相关文章:

Python:从 Web 界面运行时导入其他 python 文件

kubernetes - helm 获取子图服务名称

Pythonic 方式获取在 yaml 中定义或未定义的值

python - 算术运算中的 Yaml 类型转换变量

python - 如何使用 TensorFlow 数据集获取 Omniglot 数据对

python - 从 line.split() 中提取多个不相邻的字段

yaml - 在cloudformation模板中不同资源类型之间共享标签

python - 如何使用python保留YAML文件中键值的顺序(不是字母顺序)

python - 在 Pandas 中减去日期时间列时返回错误

json - 是否有任何基于 JSON(或 YAML)的 "time sheet"或 "work log"相关格式用于记录任务所花费的时间?