【问题标题】:Using generic constructor to read yaml file使用泛型构造函数读取 yaml 文件
【发布时间】:2019-09-25 13:19:37
【问题描述】:

我需要使用包 pyyaml 在 python 中读取 AWS cloudformation 文件。该问题似乎已使用此代码 sn-p 解决。

def generic_constructor(loader, tag, node):
    classname = node.__class__.__name__
    if (classname == 'SequenceNode'):
        return loader.construct_sequence(node)
    elif (classname == 'MappingNode'):
        return loader.construct_mapping(node)
    else:
        return loader.construct_scalar(node)

yaml.add_multi_constructor('', generic_constructor)

如何使用此代码读取 yaml 文件?

https://github.com/yaml/pyyaml/issues/169

问题已在 github 上关闭,这意味着此代码必须正常工作才能读取问题报告者链接的 yaml 文件。


答案是正确的。简而言之,有效的代码是这样的……

import yaml

def generic_constructor(loader, tag, node):
    classname = node.__class__.__name__
    if classname == "SequenceNode":
        return loader.construct_sequence(node)
    elif classname == "MappingNode":
        return loader.construct_mapping(node)
    else:
        return loader.construct_scalar(node)

yaml.add_multi_constructor("", generic_constructor, Loader=yaml.SafeLoader)

with open("mytest.yaml") as f:
    data = yaml.safe_load(f)

【问题讨论】:

  • 你的代码在哪里?您的示例 AWS sn-p 在哪里无法使用该代码?

标签: python pyyaml


【解决方案1】:

一般的想法是您的代码使用以下方式导入 PyYAML:

import yaml

然后调用 sn-p,它会修改默认加载器。由于 PyYAML 使用的默认加载器在该问题关闭后发生了变化,因此您最好指定例如SafeLoader 明确:

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

然后使用data = yaml.safe_load(open_file_or_string)加载数据。

使用 ruamel.yaml 可能更容易(免责声明:我是该包的作者),默认情况下可以处理特殊标签(包括 AWS 的标签),尽管您应该指定十年过时的 YAML 1.1 版本(这是 AWS 所期望的,也是 PyYAML 唯一支持的)。

from ruamel.yaml import YAML

yaml = YAML()
yaml.version = (1, 1)
data = yaml.load(x)

其中x 可以是pathlib.Path() 实例、打开的文件或字符串。

【讨论】:

    猜你喜欢
    • 2017-02-10
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多