Использование универсального конструктора для чтения файла yaml - PullRequest
0 голосов
/ 25 сентября 2019

Мне нужно прочитать файл облачной информации AWS на python, используя пакет pyyaml.Кажется, проблема была решена с использованием этого фрагмента кода.

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)

1 Ответ

1 голос
/ 26 сентября 2019

Общая идея заключается в том, что ваш код импортирует 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(), открытым файлом или строкой.

...