gpt4 book ai didi

python - 使用 Python 在 YAML 中保留 anchor 和别名

转载 作者:太空宇宙 更新时间:2023-11-04 00:22:46 24 4
gpt4 key购买 nike

我正在用 Python 编辑一个带有大量 anchor 和别名的大型 YAML 文档。我希望能够根据 anchor 引用的节点中的数据确定 anchor 是如何派生的。

例如,节点有一个“名称”字段,我希望 anchor 是该字段的值而不是随机 ID 号。

这可以用 PyYAML 或 ruamel.yaml 实现吗?

最佳答案

有几点需要注意:

  • YAML 没有字段。我假设这是您对映射中键的解释,因此您希望与映射关联的 anchor 与键 'name'
  • 的值相同
  • 在加载期间,遇到 anchor 时创建的事件不知道它是标量、序列还是映射上的 anchor 。更不用说它可以访问“name”的值了。
  • 在加载期间更改 anchor 很棘手,因为您必须跟踪引用原始 anchor 的别名(并将它们映射到它的新值)
  • 在 PyYAML 中, anchor 名称是在 dump-ing 期间创建的,因此您在使用 PyYAML 时必须挂接到它。您可以使用 ruamel.yaml
  • 执行相同的操作
  • 只有 ruamel.yaml 能够在往返过程中保留 anchor 。 IE。如果您可以使 anchor 持久化,即使键“name”的值发生变化(假设您在默认生成的表单 idNNNN 上进行测试)

当您使用 ruamel.yaml 时,您可以递归遍历数据结构,跟踪已经访问过的节点(以防子节点包含祖先)以及遇到 ruamel.yaml .comments.CommentedMap,设置 anchor (当前值为ruamel.yaml.comments.Anchor.attrib_yaml_anchor的属性)。未经测试的代码:

if isinstance(x, ruamel.yaml.comments.CommentedMap):
if 'name' in x:
x.yaml_set_anchor(x['name'])

如果您有一个可以往返的 YAML 文档,您可以连接到表示器:

import sys
import ruamel.yaml
from ruamel.yaml.representer import RoundTripRepresenter

yaml_str = """\
# data = [dict(a=1, b=2, name='mydata'), dict(c=3)]
# data.append(data[0])
- &id001
a: 1
b: 2
name: mydata
- c: 3
- *id001
"""

class MyRTR(RoundTripRepresenter):
def represent_mapping(self, tag, mapping, flow_style=None):
if 'name' in mapping:
# if not isinstance(mapping, ruamel.yaml.comments.CommentedMap):
# mapping = ruamel.yaml.comments.CommentedMap(mapping)
mapping.yaml_set_anchor(mapping['name'])

mapping.yaml_set_anchor(mapping['name'])
return RoundTripRepresenter.represent_mapping(
self, tag, mapping, flow_style=flow_style)


yaml = ruamel.yaml.YAML()
yaml.Representer = MyRTR
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

给出:

# data = [dict(a=1, b=2, name='mydata'), dict(c=3)]
# data.append(data[0])
- &mydata a: 1
b: 2
name: mydata
- c: 3
- *mydata

但请注意,这假设您加载了数据并且所有 dict 实际上都是 CommentedMap 的。如果不是这种情况(即您添加了普通的 dict,然后取消对进行转换的两行的注释。

关于python - 使用 Python 在 YAML 中保留 anchor 和别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48551508/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com