pyYAML ошибки на "!"в строку

во-первых, отказ от ответственности: я не слишком хорошо знаком с YAML. Я пытаюсь разобрать документ YAML на пары ключевых значений (не беспокойтесь о том, как я это делаю. Я немного обработал)

мой файл раньше выглядел примерно так:

world:
     people:
          name:Suzy
          address:chez-bob

затем кто-то пошел и изменил его.

world:
     people:
          name:!$uzy
          address:chez-bob

и я получаю эту ошибку разбора:

yaml.constructor.ConstructorError: could not determine a constructor for the tag '!$uzy'

что это вообще значит? Как мне заставить его просто интерпретировать !$ как всего два персонажа? Я просто хочу словарь строковых ключей и значений! Кроме того, редактирование файлов yaml не является опцией. Проблема должна быть исправлена в коде с помощью парсера.

3 ответов


восклицательный знак-это префикс для тегов YAML. Парсер должен реализовать конструктор по имени тега. Есть некоторые теги вроде !!bool, !!int, etc. и даже некоторые специфические теги Python, такие как !!python/tuple.

вы можете определить свои собственные конструкторы и даже конструкторы для нескольких тегов поймал префикса. Определив префикс '', вы можете поймать все теги и игнорировать их. Вы можете вернуть тег и его значение из конструктора, чтобы просто лечить ее все как текст.

>>> import yaml
>>> def default_ctor(loader, tag_suffix, node):
...     print loader
...     print tag_suffix
...     print node
...     return tag_suffix + ' ' + node.value
...
>>> yaml.add_multi_constructor('', default_ctor)
>>> yaml.load(y)
<yaml.loader.Loader object at 0xb76ce8ec>
!$uzy
ScalarNode(tag=u'!$uzy', value=u'')
{'world': {'people': {'name': '!$uzy', 'address': 'chez-bob'}}}
>>>

Если значение начинается с "!", вы должны заключить значение в одинарные или двойные кавычки; в противном случае оно интерпретируется как тег YAML.

world:
     people:
          name: "!$uzy"
          address: chez-bob

это на самом деле ошибка в PyYAML. Он интерпретирует : на name:!$uzy как разделитель ключа / значения, но он должен делать это только если : стоит пробел, или, если предыдущий скаляр (name) цитирует. Последующая ошибка заключается в том, что восклицательный знак, который должен быть разрешен в середине скаляра, неправильно интерпретируется как находящийся в начале скаляра и, следовательно, вводящий тег.

значение ключа people строка name:!$uzy address:chez-bob и это корректно обрабатывается в других синтаксических анализаторах (включая пакет Python ruamel.yaml из которых я являюсь автором).