2016-10-24 2 views
2

Я пытаюсь сбрасывать питон Python в файл YAML, используя ruamel.yaml. Я знаком с интерфейсом json модуля, где довольно-печать Dict это так просто, какruamel.yaml эквивалент sort_keys?

import json 
with open('outfile.json', 'w') as f: 
    json.dump(mydict, f, indent=4, sort_keys=True) 

С ruamel.yaml, я получил, насколько

import ruamel.yaml 
with open('outfile.yaml', 'w') as f: 
    ruamel.yaml.round_trip_dump(mydict, f, indent=2) 

, но это не кажется для поддержки опции sort_keys. ruamel.yaml также doesn't seem to have any exhaustive docs, и поиск Google для «ruamel.yaml sort» или «ruamel.yaml alphabetize» не стал ничем на уровне простоты, которую я ожидал бы.

Есть ли один-два вкладыша для красивой печати файла YAML со отсортированными ключами?

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


Обратите внимание, что если я использую round_trip_dump, ключи не отсортировано; и если я использую safe_dump, выход не является «YAML-стилем» (или, что более важно, «Kubernetes-style») YAML. Я не хочу [] или {} в моем выходе.

$ pip freeze | grep yaml 
ruamel.yaml==0.12.5 

$ python 
>>> import ruamel.yaml 
>>> mydict = {'a':1, 'b':[2,3,4], 'c':{'a':1,'b':2}} 
>>> print ruamel.yaml.round_trip_dump(mydict) # right format, wrong sorting 
a: 1 
c: 
    a: 1 
    b: 2 
b: 
- 2 
- 3 
- 4 

>>> print ruamel.yaml.safe_dump(mydict) # wrong format, right sorting 
a: 1 
b: [2, 3, 4] 
c: {a: 1, b: 2} 
+0

Вы смотрели на параметры safe_dump в нижней части моего ответа? – Anthon

ответ

1

Это:

import sys 
import ruamel.yaml 

mydict = dict(a1=1, a2=2, a3=3, a11=11, a21=21) 
ruamel.yaml.round_trip_dump(mydict, sys.stdout) 

дает не-отсортированный вывод. На моей системе:

a11: 11 
a2: 2 
a21: 21 
a3: 3 
a1: 1 

, добавив:

my_sorted_dict = ruamel.yaml.comments.CommentedMap() 
for k in sorted(mydict): 
    my_sorted_dict[k] = mydict[k] 
ruamel.yaml.round_trip_dump(my_sorted_dict, sys.stdout) 

это будет сортироваться:

a1: 1 
a11: 11 
a2: 2 
a21: 21 
a3: 3 

Закомментированный карта структура ruamel.yaml использует при выполнении туда-обратно (нагрузка + дамп) и круглое отключение предназначены для хранения ключей в том порядке, в котором они были раньше.

Если вы загрузили mydict из файла YAML и нужно только добавить несколько клавиш, вы можете ходить по ключам mydict «s и вставить (mydict.insert(pos, new_key, new_value)) ключевые пары значений.

Конечно, вы можете получить тот же результат, делая нормальный safe_dump(), если вам не нужны какие-либо другие специальные функции:

ruamel.yaml.safe_dump(mydict, sys.stdout, allow_unicode=True, 
         default_flow_style=False) 
+0

Ого, это 'default_flow_style = False' соответствующий способ включения вывода YAML в стиле Кубернете? Я могу попробовать. – Quuxplusone

+0

Это своего рода отдельный вопрос, и я могу задать его отдельно, если вам нравится, но теперь мне интересно: есть ли хороший способ указать «сортировать ключи по умолчанию», но если есть ключ с именем 'name', поставьте он сначала ", снова применяя рекурсивно ко всей структуре? Если бы это было так, я бы использовал его. – Quuxplusone

+0

@Quuxplusone Просто поместите туда ('name', value) пару или используйте' .insert() ', как я указал. Вы также можете написать определенный сериализатор, который знает о 'name', но из-за того, что был реализован PyYAML (и румаль.yaml), трудно параметризировать это для любого ключа (и для этого ответа потребуется отдельный вопрос). – Anthon

Смежные вопросы