gpt4 book ai didi

python - 如果 YAML 中存在 '!',如何使用 PyYAML 解析 YAML

转载 作者:太空宇宙 更新时间:2023-11-03 14:42:29 24 4
gpt4 key购买 nike

我有一个 YAML 文件,我只想解析 description 变量;但是,我知道我的 CloudFormation 模板(YAML 文件)中的感叹号给 PyYAML 带来了麻烦。

我收到以下错误:

yaml.constructor.ConstructorError:无法确定标记“!Equals”的构造函数

该文件有许多 !Ref!Equals。如何忽略这些构造函数并获取我正在寻找的特定变量 - 在本例中为 description 变量。

最佳答案

如果您必须处理具有多个不同标签的 YAML 文档,并且仅对其中的一部分感兴趣,您仍然应该处理所有这些。如果您感兴趣的元素是嵌套的在其他标记结构中,您至少需要处理所有“封闭”标记正确地。

但是没有必要单独处理所有标签,您可以编写可以处理映射、序列的构造函数例程标量使用以下方法将其注册到 PyYAML 的 SafeLoader:

import yaml

inp = """\
MyEIP:
Type: !Join [ "::", [AWS, EC2, EIP] ]
Properties:
InstanceId: !Ref MyEC2Instance
"""

description = []

def any_constructor(loader, tag_suffix, node):
if isinstance(node, yaml.MappingNode):
return loader.construct_mapping(node)
if isinstance(node, yaml.SequenceNode):
return loader.construct_sequence(node)
return loader.construct_scalar(node)

yaml.add_multi_constructor('', any_constructor, Loader=yaml.SafeLoader)

data = yaml.safe_load(inp)
print(data)

给出:

{'MyEIP': {'Type': ['::', ['AWS', 'EC2', 'EIP']], 'Properties': {'InstanceId': 'MyEC2Instance'}}}

(inp也可以是打开用于读取的文件)。

正如您在上面看到的,如果代码中出现意外的 !Join 标记,该功能也将继续工作,以及任何其他标签,如 !Equal。标签刚刚被删除。

由于 YAML 中没有变量,所以需要猜测一下你的意思是“喜欢只解析描述变量”。如果那有显式标记(例如 !Description),您可以通过添加 2-3 行来过滤掉值通过匹配 tag_suffix 参数来连接到 any_constructor

    if tag_suffix == u'!Description':
description.append(loader.construct_scalar(node))

然而,映射中更有可能存在一些标量描述的键,并且您对该键关联的值感兴趣。

    if isinstance(node, yaml.MappingNode):
d = loader.construct_mapping(node)
for k in d:
if k == 'description':
description.append(d[k])
return d

如果您知道数据层次结构中的确切位置,您可以当然还可以遍历data结构并提取您需要的任何内容基于键或列表位置。尤其是在这种情况下你会更好使用我的 ruamel.yaml,这是否可以在往返模式下加载标记的 YAML,而无需额外的努力(假设上面的inp):

from ruamel.yaml import YAML

with YAML() as yaml:
data = yaml.load(inp)

关于python - 如果 YAML 中存在 '!',如何使用 PyYAML 解析 YAML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52240554/

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