Сохранение / дамп файла YAML с комментариями в PyYAML

У меня есть файл yaml, который выглядит так:

# The following key opens a door
key: value

Есть ли способ load и dump эти данные, сохраняя при этом комментарий?


person Harley Holcombe    schedule 31.08.2011    source источник
comment
Однажды я модифицировал код C libyaml, чтобы оставлять комментарии для собственного использования. Распространить это на PyYAML будет непросто.   -  person David Heffernan    schedule 31.08.2011
comment
Я снова подумал об этом. Имеет ли смысл разбирать и писать файл yaml, который редактировался вручную (и будет отредактирован вручную в будущем)? Почему бы не разделить файл на две части: одна создана вручную, а другая - чистые данные (без комментариев). По теме: github.com/guettli/programming-guidelines/blob/master/   -  person guettli    schedule 16.09.2019


Ответы (3)


PyYAML отбрасывает комментарии на очень низком уровне (в Scanner.scan_to_next_token).

Хотя вы можете адаптировать или расширить его для обработки комментариев во всем стеке, это будет серьезная модификация. Dumping (= создание) комментариев кажется проще, и это обсуждалось в билет 114 на старом трекере ошибок PyYAML.

По состоянию на 2020 год запрос функции о добавлении поддержки загрузки комментариев все еще откладывается.

person phihag    schedule 31.08.2011
comment
Вы правы, это была серьезная модификация, хотя и проще, потому что я отказался от поддержки 2.6 и перекомпоновал исходники Py2 и Py3. - person Anthon; 24.11.2014

Если вы используете YAML с блочной структурой, вы можете использовать пакет python¹ ruamel.yaml, который является производная от PyYAML и поддерживает сохранение комментариев в оба конца:

import sys
import ruamel.yaml

yaml_str = """\
# example
name:
  # details
  family: Smith   # very common
  given: Alice    # one of the siblings
"""

yaml = ruamel.yaml.YAML()  # defaults to round-trip if no parameters given
code = yaml.load(yaml_str)
code['name']['given'] = 'Bob'

yaml.dump(code, sys.stdout)

с результатом:

# example
name:
  # details
  family: Smith   # very common
  given: Bob      # one of the siblings

Обратите внимание, что комментарии в конце строки все еще выровнены.

Вместо обычных объектов list и dict объект code состоит из обернутых версий², к которым прикреплены комментарии.

¹ Установить с pip install ruamel.yaml. Работает на Python 2.6 / 2.7 / 3.3 +
² ordereddict используется в случае сопоставления для сохранения порядка

person Anthon    schedule 24.11.2014
comment
Это не отвечает на вопрос OP. Сохраняет порядок, но не комментарии. - person Cerin; 23.01.2017
comment
@cerin Какие комментарии отсутствуют при запуске вышеуказанного кода? С какой версией Python, ruamel.yaml и на какой платформе вы запускали этот код? Я просто повторил это с последней версией ruamel.yaml (на случай, если я что-то сломал), но вывод все еще включает комментарии. Учитывая количество голосов здесь, я думаю, что другие смогли получить такой же результат, и что вы, возможно, что-то упустили. - person Anthon; 23.01.2017
comment
@Anthon, вроде непоследовательно. В вашем примере комментарии сохраняются, но в более сложных файлах yaml, которые я тестировал, он удаляет некоторые комментарии, особенно если вы редактируете данные рядом с этими комментариями. Я использую самую последнюю версию пакета с Python 2.7. - person Cerin; 24.01.2017
comment
@cerin Изначально круговое отключение использовалось для обновления значений в файле конфигурации, который всегда должен работать. Как все сохранилось, если вы начнете удалять ключи, то комментарии могут исчезнуть. Я бы предпочел, чтобы вы задали вопрос об этом на Stack Overflow или отправили отчет об ошибке. Я стараюсь что-то исправить, если могу, и пытаюсь найти обходные пути или, по крайней мере, объяснение, если не могу. - person Anthon; 24.01.2017
comment
Если кому-то нужно более стандартное форматирование YAML, вы можете использовать yaml.indent(mapping=2, sequence=4, offset=2) перед выполнением dump - person The Godfather; 01.04.2020

У меня есть ветка pyyaml, которая делает именно это. https://github.com/pflarr/pyyaml

Чтобы создать файл yaml с комментариями, вы должны создать поток событий, который включает события комментариев. Комментарии в настоящее время разрешены только перед элементами последовательности и ключами сопоставления.

В настоящее время это работает только для python3, я не портировал его в версию библиотеки для python2, но могу легко сделать это по запросу. Кроме того, это также должно быть довольно легко перенести на C libyaml, так как код python в любом случае является простым портом для этого.

person Paul Ferrell    schedule 10.01.2018