PyYAML на самом деле не предназначен для выполнения таких двусторонних обновлений, он падает
любые комментарии, которые вы можете иметь, и не обязательно сохранять порядок ключей
отображений.
Я рекомендую вам взглянуть на
ruamel.yaml (отказ от ответственности: я
автор этого пакета) по нескольким причинам, включая, но не
ограничено:
- поддержка YAML 1.2 (но может записывать / читать YAML 1.1 при необходимости)
- сохранение комментариев, порядка ключей, имен якорей / псевдонимов, форматов с плавающей запятой / целых чисел
- более точный контроль над отступами отображений и списков
- нет необходимости загружать все документы, обрабатывать их и выгружать за один раз
- необязательное сохранение кавычек и / или скаляров блочного стиля
- безопасная загрузка по умолчанию и предупреждение, если вы используете небезопасный
load
в
обратно совместимый API
- исправление многих ошибок
from pathlib import Path
from ruamel.yaml import YAML
path = Path('testing.yaml')
tmp_path = path.with_suffix('.yaml.tmp')
with YAML(output=tmp_path) as yaml:
# yaml.indent(mapping=4, sequence=4, offset=2)
# yaml.preserve_quotes = True
for data in yaml.load_all(path):
# update data
yaml.dump(data)
path.unlink()
tmp_path.rename(path)
print(path.read_text(), end='')
, что дает:
apiVersion: v1
data:
databag1: try this
databag2: then try this
kind: ConfigMap
metadata:
name: data bag info
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: data-bag-service
name: data-bag-tagging
Обратите внимание, что вы не можете писать и читать из того же файла, что и вы
обрабатывают документ за один раз. Отсюда временный файл, который
имеет дополнительное преимущество, что если вы получаете ошибку при обновлении
этот последний документ и ваша программа падает, вы не остаетесь с
наполовину записанный поток YAML.