Формат дампа PyYAML
Я знаю, что есть несколько вопросов об этом на SO, но я не мог найти то, что искал.
Я использую pyyaml для чтения ( .load()
) файла .yml
, изменения или добавления ключа, а затем пишу его ( .dump()
) еще раз. Проблема в том, что я хочу сохранить формат файла post-dump, но он изменяется.
- Разбор YAML и Python?
- Можно ли использовать блоки метаданных yaml для расширения синтаксиса pandoc?
- Чтение YAML в python
- Преобразование CSV в YAML, с Unicode?
- Как предотвратить YAML для сбрасывания длинной строки без новой строки
Например, я редактирую ключ en.test.index.few
чтобы сказать "Bye"
вместо "Hello"
Python:
with open(path, 'r', encoding = "utf-8") as yaml_file: self.dict = pyyaml.load(yaml_file)
Затем, изменив ключ:
with open(path, 'w', encoding = "utf-8") as yaml_file: dump = pyyaml.dump(self.dict, default_flow_style = False, allow_unicode = True, encoding = None) yaml_file.write( dump )
YAML:
До:
en: test: new: "Bye" index: few: "Hello" anothertest: "Something"
После:
en: anothertest: Something test: index: few: Hello new: Bye
Есть ли способ сохранить тот же формат ?, например, qoutes и order. Использую ли я для этого неправильный инструмент?
Я знаю, возможно, исходный файл не совсем корректен, но я не контролирую его (это файл Ruby on Rails i18n).
Большое спасибо.
- словарь yaml multi вложен и словарь python
- Разбор YAML, возврат с номером строки
- Как я могу контролировать, какую скалярную форму PyYAML использует для моих данных?
- Есть ли выигрыш в производительности от определения маршрутов в app.yaml по сравнению с одним большим отображением в WSGIApplication в AppEngine?
- как писать файл yaml
3 Solutions collect form web for “Формат дампа PyYAML”
ruamel.yaml
этого используйте ruamel.yaml
.
Библиотека битвы! Сказка о двух библиотеках
PyYAML эффективно мертв и уже несколько лет. Что касается сложных вопросов, официальный сайт проекта на http://pyyaml.org, похоже, недавно был снят. На этом сайте размещен трекер, документация и загрузки PyYAML. На момент написания статьи все исчезло. Это не что иное, как бедствие. Добро пожаловать в другой день в open-source.
ruamel.yaml
активно поддерживается . В отличие от PyYAML, ruamel.yaml
поддерживает:
- YAML <= 1.2. PyYAML поддерживает только YAML <= 1.1. Это очень важно, поскольку YAML 1.2 намеренно нарушает обратную совместимость с YAML 1.1 в нескольких случаях. Обычно это плохо. В этом случае это делает YAML 1.2 строгим надмножеством JSON. Поскольку YAML 1.1 не является строгим надмножеством JSON, это хорошо.
- Круглосуточная охрана. При вызове
yaml.dump()
для дампа словаря, загруженного предыдущим вызовомyaml.load()
:- PyYAML наивно игнорирует все форматирование ввода – включая комментарии, заказы, цитаты и пробелы. Отброшено, как много цифровых отходов в ближайшее доступное ведро бит.
-
ruamel.yaml
умело уважает все форматирование ввода. Все. Вся стилистическая энчилада. Весь литературный шебанг. Все.
Миграция библиотек: следы кодовых слез
Поскольку ruamel.yaml
является вилкой PyYAML и, следовательно, соответствует API PyYAML, переключение с PyYAML на ruamel.yaml
в существующих приложениях обычно так же просто, как и замена всех экземпляров этого:
# This imports PyYAML. Stop doing this. import yaml
…с этим:
# This imports "ruamel.yaml". Always do this. from ruamel import yaml
Вот и все.
Никаких других изменений не требуется. Функции yaml.load()
и yaml.dump()
должны продолжать вести себя так, как ожидалось, – с дополнительными преимуществами теперь поддерживая YAML 1.2 и активно получая исправления ошибок.
Сохранение заграничных кругов и что он может сделать для вас
Для обратной совместимости с PyYaml функции yaml.load()
и yaml.dump()
по умолчанию не поддерживают сохранение в yaml.load()
. Для этого явно передайте:
- Необязательный параметр ключевого слова
Loader=ruamel.yaml.RoundTripLoader
дляyaml.load()
. - Необязательный параметр ключевого слова
Dumper=ruamel.yaml.RoundTripDumper
дляyaml.dump()
.
Пример любезно «заимствован» из документации ruamel.yaml
:
import ruamel.yaml inp = """\ # example name: # Yet another Great Duke of Hell. He's not so bad, really. family: TheMighty given: Ashtaroth """ code = ruamel.yaml.load(inp, Loader=ruamel.yaml.RoundTripLoader) code['name']['given'] = 'Astarte' # Oh no you didn't. print(ruamel.yaml.dump(code, Dumper=ruamel.yaml.RoundTripDumper), end='')
Сделано. Комментарии, заказы, цитаты и пробелы теперь будут сохранены без изменений.
ТЛ; др
Всегда используйте ruamel.yaml
. Никогда не используйте PyYAML. ruamel.yaml
живет. PyYAML – это зловонный труп, гниющий на измельченном грунте PyPi.
Да здравствует ruamel.yaml
.
Первый
Для представления данных словаря используется следующий код:
mapping = list(mapping.items()) try: mapping = sorted(mapping) except TypeError: pass
Именно поэтому заказ меняется
второй
Информация о том, как был представлен тип скаляра (с двойной кавычкой или нет), теряется при чтении (это основной подход библиотеки)
Резюме
Вы можете создать собственный класс на основе «Dumper» и перегрузить метод «Represent_mapping» для изменения поведения, как будет отображаться словарь
Для сохранения информации о двойных кавычках для скаляра вы также должны создать собственный класс на основе «Loader», но я боюсь, что это повлияет и на другие классы, и это будет сложно
В моем случае я хочу, "
если значение содержит {
или a }
, в противном случае ничего. Например:
en: key1: value is 1 key2: 'value is {1}'
Чтобы выполнить это, скопируйте функцию Represent_str represent_str()
из файла representer.py в модуль PyYaml и используйте другой стиль, если строка содержит {
или a }
:
def represent_str(self, data): tag = None style = None # Add these two lines: if '{' in data or '}' in data: style = '"' try: data = unicode(data, 'ascii') tag = u'tag:yaml.org,2002:str' except UnicodeDecodeError: try: data = unicode(data, 'utf-8') tag = u'tag:yaml.org,2002:str' except UnicodeDecodeError: data = data.encode('base64') tag = u'tag:yaml.org,2002:binary' style = '|' return self.represent_scalar(tag, data, style=style)
Чтобы использовать его в своем коде:
import yaml def represent_str(self, data): ... yaml.add_representer(str, represent_str)
В этом случае нет различий между клавишами и значениями, и этого достаточно для меня. Если вам нужен другой стиль для клавиш и значений, выполните одно и то же с функцией represent_mapping
- Как использовать модуль win32gui с Python?
- Как получить список открытых окон в PyGTK или GTK в Ubuntu?