Как я могу добавить кортеж Python в файл YAML, используя pyYAML? - PullRequest
7 голосов
/ 07 февраля 2012

Название довольно очевидно.

Когда я сохраняю кортеж в файл YAML, я получаю что-то похожее на это:

ambient:  !!python/tuple [0.3, 0.3 ,0.3]

Когда я пытаюсь загрузить его с помощью yaml.safe_load (file_object), я получаю сообщение об ошибке:

yaml.constructor.ConstructorError:  could not determine a constructor for the tag 'tag:yaml.org,2002:python/tuple'

Что нужно сделать?

Ответы [ 2 ]

11 голосов
/ 07 февраля 2012

В pyyaml ​​SafeLoader не включает загрузчик для собственных типов Python, а только типы, определенные в спецификации yaml.Вы можете увидеть типы для SafeLoader и Loader здесь в примере взаимодействия ниже.

Вы можете определить новый класс Loader, который добавляет в кортеж python, но не другие типы, поэтому он долженвсе еще быть довольно безопасным:

import yaml

class PrettySafeLoader(yaml.SafeLoader):
    def construct_python_tuple(self, node):
        return tuple(self.construct_sequence(node))

PrettySafeLoader.add_constructor(
    u'tag:yaml.org,2002:python/tuple',
    PrettySafeLoader.construct_python_tuple)

doc = yaml.dump(tuple("foo bar baaz".split()))
print repr(doc)
thing = yaml.load(doc, Loader=PrettySafeLoader)
print thing

, что приводит к:

'!!python/tuple [foo, bar, baaz]\n'
('foo', 'bar', 'baaz')

Ниже приведены конструкторы, связанные с классами SafeLoader и Loader.

0 голосов
/ 07 февраля 2012

По крайней мере, согласно документации PyYAML :

Функция yaml.safe_load ограничивает эту возможность простыми объектами Python, такими как целые числа или списки.

Список , как вы можете видеть в источнике , несколько более обширен, но не включает tag:yaml.org,2002:python/tuple.

Похоже, что если вы генерируете тип !!python/tuple вваш файл YAML, вы используете dump() вместо safe_dump().В этом случае вам, вероятно, следует перейти на использование load() вместо safe_load(), поскольку файлы, созданные с помощью dump(), не гарантированно будут загружаться safe_load().(См. описание safe_dump()).

...