使用泛型构造器读取yaml文件

Using generic constructor to read yaml file

我需要使用 pyyaml 包读取 python 中的 AWS cloudformation 文件。使用此代码段似乎已解决此问题。

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)

总体思路是您的代码使用以下方式导入 PyYAML:

import yaml

然后您调用代码段,它修改了默认加载器。由于自该问题关闭以来 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() 实例、打开的文件或字符串。