Как сохранить комментарии в руамеле - PullRequest
0 голосов
/ 19 декабря 2018

Мне нужно отсортировать файл YAML с комментариями.Я использую библиотеку ruamel.yaml для хранения комментариев от YAML, но когда я сортирую элементы, комментарии помещаются в неправильное место.

people = """\
# manager of project
- title: manager

# owner of company
- title: owner
"""

import ruamel.yaml, sys

yaml = ruamel.yaml.YAML()
arr = yaml.load(people)
arr  = sorted(arr, key=lambda x: x['title'])
yaml.dump(arr, sys.stdout)

С этим кодом я получаю следующий вывод:

- title: manager

# owner of company
- title: owner

Во время сортировки комментарий для первого элемента пропал.Как я могу оставить первый комментарий к списку?

1 Ответ

0 голосов
/ 19 декабря 2018

Ваш первый комментарий в начале документа не имеет предшествующего узла и занимает особое место в объекте arr (тип ruamel.yaml.comments.CommentedSeq).Вы можете проверить это, выполнив print(arr.ca) (ca для атрибута комментария), непосредственно после загрузки.

После загрузки к объекту, подобному dict, прикреплен второй атрибут комментария, созданный из сопоставления arr[0], и третийАтрибут комментария прикреплен к объекту, похожему на вихрь, сконструированному из arr[1] (во многом так же, как первый комментарий прикреплен к arr).

Операция сортировки не , выполненная вместо, следовательно, остаются только комментарии, связанные с отсортированными элементами.arr после присвоения (простое list) результата sorted() даже не совпадает с типом arr, загруженным из YAML (a CommentedSeq), и, конечно, не имеет комментариев, связанныхс ним.

Итак, вам нужно сохранить информацию комментария, сделать результат сортировки соответствующего типа, а затем присвоить сохраненную информацию этому объекту.К счастью, для этого требуется только одна измененная и одна добавленная строка к вашему коду:

import sys
import ruamel.yaml

people = """\
# manager of project
- title: manager

# owner of company
- title: owner
"""

yaml = ruamel.yaml.YAML()
arr = yaml.load(people)
root_comment = arr.ca
arr  = ruamel.yaml.comments.CommentedSeq(sorted(arr, key=lambda x: x['title']))
arr._yaml_comment = root_comment
yaml.dump(arr, sys.stdout)

, что дает:

# manager of project
- title: manager

# owner of company
- title: owner

Однако в целом подобные интенсивные манипуляции могут привести к неприятностям.Вероятно, лучше попробовать сделать это с сортировкой на месте.

...