Если вы прочитаете документацию PyYAML, вы увидите, что она говорит вам, что использование функции load()
потенциально опасно, поэтому первое, что нужно сделать (так как вам и почти всем остальным это не нужно),не использует это, но вместо этого использует safe_load()
.
Вы также должны изменить свой входной файл на config.yaml
, рекомендуемое расширение для файлов YAML было .yaml
с 2006 года.
Зная это, способ изменить файл config.yaml
с помощью PyYAML:
import yaml
with open('config.yaml') as stream:
data = yaml.safe_load(stream)
test = data['test']
test.update(dict(name="Tom", age="10", version="2.2"))
with open('output.yaml', 'wb') as stream:
yaml.safe_dump(data, stream, default_flow_style=False,
explicit_start=True, allow_unicode=True, encoding='utf-8')
Это даст вам output.yaml
, который выглядит следующим образом:
---
test:
age: '10'
name: Tom
version: '2.2'
Параметр default_flow_style
необходим, чтобы не получить JSON-подобную структуру для отображения вашего конечного узла.explicit_start
, чтобы получить индикатор окончания ведущих директив (---
), и я рекомендую всегда использовать allow_unicode=True, encoding='utf-8'
(и открывать файл как двоичный файл), чтобы избежать неожиданностей или проблем при изменении name
наBjörk Guðmundsdóttir
.
Теперь, как вы заметите, это не генерирует желаемый результат (хотя семантически тот же):
- одинарные кавычки вместо двойных кавычек вокругстроки, которые можно интерпретировать как числа
- без двойных кавычек вокруг
Tom
- сортировка ключей вашего сопоставления
Если у вас есть какие-либо комментарии в YAMLфайл, они были бы потеряны.
Лучшим способом обновления YAML-файлов является использование ruamel.yaml
(отказ от ответственности: я являюсь автором этого пакета), который имеет несколько более значительных значений по умолчанию, чем PyYAML, обрабатывает YAML 1.2 и не пропускает комментарии (есливы должны иметь их в своем файле):
import ruamel.yaml
yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
yaml.explicit_start = True
with open('config.yaml') as stream:
data = yaml.load(stream)
test = data['test']
test.update(dict(name="Tom", age="10", version="2.2"))
with open('output.yaml', 'wb') as stream:
yaml.dump(data, stream)
с этим ваш выходной файл будет:
---
test:
name: "Tom"
age: "10"
version: "2.2"
, что именно то, что вы хотели.