Для сериализации объекта Python в поток YAML необходимо использовать функцию yaml.dump(data, stream)
модуля PyYAML.
Примечание: кроме того, можно использовать функцию yaml.safe_dump(data, stream)
, которая не поддерживает произвольные объекты Python. При использовании функции yaml.safe_dump()
будут сгенерированы только стандартные теги YAML.
Смотрим простой пример преобразования словаря Python в поток YAML.
import yaml # словарь Python py_obj = {'name': 'Silenthand Olleander', 'race': 'Human', \ 'traits': ['ONE_HAND', 'ONE_EYE']} # сериализуем `py_obj` в формат YAML yml_doc = yaml.dump(py_obj) # смотрим, что получилось print(yml_doc) # name: Silenthand Olleander # race: Human # traits: # - ONE_HAND # - ONE_EYE
Используя функцию yaml.dump()
, можно переводить объекты Python в формат YAML и записывать их в файлы YAML, чтобы использовать в будущем. Этот процесс известен как сериализация YAML.
Функция yaml.dump(data, stream=None)
принимает два аргумента:
data
- это объект Python, который будет сериализован в поток YAML,stream
должен быть открытым текстовым или двоичным файлом.Если указаны оба аргумента, то yaml.dump()
запишет созданный документ YAML в файл, в противном случае функция возвращает созданный документ.
import yaml # словарь Python user = {'UserName': 'Alice', 'Password': 'star123*', 'phone': 3256, 'AccessKeys': ['EmployeeTable', 'SoftwaresList', 'HardwareList']} # открываем файл на запись with open('test.yaml', 'w') as fw: # сериализуем словарь `user` в формат YAML # и записываем все в файл `test.yaml` data = yaml.dump(user, fw, sort_keys=False, default_flow_style=False) # смотрим, что получилось with open('test.yaml', 'r') as fr: print(fr.read()) # UserName: Alice # Password: star123* # phone: 3256 # AccessKeys: # - EmployeeTable # - SoftwaresList # - HardwareList
Так же, функция yaml.dump()
, принимает несколько ключевых аргументов:
default_flow_style=False
: используется для отображения содержимого вложенных блоков с правильным отступом. По умолчанию, стиль отображения содержимого блока принимает правильный отступ. При значении default_flow_style=True
, значения внутри вложенных элементов отображаются в стиле потока. sort_keys=True
: используется для сортировки ключей в алфавитном порядке. Значение по умолчанию True
. Для сохранения оригинального порядка ключей словаря, используйте sort_keys=False
.explicit_start
: создает начало документа YAML (добавляет в начало '---'
).indent
: чтобы установить предпочтительный отступ,width
: установка предпочтительной ширины,canonical=True
: устанавливает предпочтительный стиль для коллекций.При сериализации объектов Python в документ YAML можно указывать параметры форматирования, используя следующие ключевые аргументы: indent
, width
и canonical
.
Примеры форматирования документов YAML при сериализации:
# форматирование списка lst = list(range(50)) print(yaml.dump(lst, width=50, indent=4, default_flow_style=True)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] # форматирование диапазона `range()` print(yaml.dump(range(5), canonical=True)) # --- # !!python/object/apply:builtins.range [ # !!int "0", # !!int "5", # !!int "1", # ] print(yaml.dump(range(5), default_flow_style=False)) # !!python/object/apply:builtins.range # - 0 # - 5 # - 1 print(yaml.dump(range(5), default_flow_style=True, default_style='"')) # !!python/object/apply:builtins.range [!!int "0", !!int "5", !!int "1"]
Если вам нужно сбросить несколько документов YAML в один поток, используйте функцию yaml.dump_all()
. Функция yaml.dump_all(lst, fp)
принимает список или генератор, производящий объекты Python для сериализации в документ YAML. Второй необязательный аргумент - открытый файл.
Смотрим как это работает на простом списке:
lst = [1, 2, 3] # простой дамп yml = yaml.dump(lst, explicit_start=True) print(yml) # --- # - 1 # - 2 # - 3 # дамп с разделением по документам YAML # обратите внимание, что у каждого значения # есть начало документа `---` yml = yaml.dump_all(lst, explicit_start=True) print(yml) # --- 1 # --- 2 # --- 3 # ...
Ну а если серьезно, то смотрим полный пример:
# допустим есть объекты class Hero(): def __init__(self, name, hp, sp): self.name = name self.hp = hp self.sp = sp class Monster(): def __init__(self, name, hp, attacks): self.name = name self.hp = hp self.attacks = attacks lst = [1, 2, 3, 4, 5, 6, 7] py_obj = {'name': 'Silenthand Olleander', 'race': 'Human', 'traits': ['ONE_HAND', 'ONE_EYE']} user = {'UserName': 'Alice', 'Password': 'star123*', 'phone': 3256, 'AccessKeys': ['EmployeeTable', 'SoftwaresList', 'HardwareList']} # определяем документы для сохранения в YAML doc1 = {'lst': lst, 'py_obj': py_obj} doc2 = {'user': user} hero = Hero('Welthyr Syxgon', 1200, 0) monster = Monster('Spider', 16, ['BITE', 'HURT']) doc3 = {'hero': hero, 'monster': monster} # объединяем документы в список для сериализации по разным документам docs_yml = [doc1, doc2, doc3] # дамп с разделением по документам YAML yml = yaml.dump_all(docs_yml, explicit_start=True) print(yml) # --- # lst: # - 1 # - 2 # - 3 # - 4 # - 5 # - 6 # - 7 # py_obj: # name: Silenthand Olleander # race: Human # traits: # - ONE_HAND # - ONE_EYE # --- # user: # AccessKeys: # - EmployeeTable # - SoftwaresList # - HardwareList # Password: star123* # UserName: Alice # phone: 3256 # --- # hero: !!python/object:__main__.Hero # hp: 1200 # name: Welthyr Syxgon # sp: 0 # monster: !!python/object:__main__.Monster # attacks: # - BITE # - HURT # hp: 16 # name: Spider