I have this example YAML file:
---
test:
name: "Tom"
age: "5"
version: "1.0"
How can I replace this YAML file to this:
test:
name: "Max"
age: "10"
version: "2.2"
This is the way I open the file:
import yaml
with open("config.yml", 'r') as stream:
print(yaml.load(stream))
But I have no idea, how to edit the YAML file now.
Given the fact that you use PyYaml
, the appropriate way to do this is like this:
#!/usr/bin/env python
import yaml
with open("testfile.yaml", 'r') as stream:
try:
loaded = yaml.load(stream)
except yaml.YAMLError as exc:
print(exc)
# Modify the fields from the dict
loaded['test']['name'] = "Max"
loaded['test']['age'] = "10"
loaded['test']['version'] = "2.2"
# Save it again
with open("modified.yaml", 'w') as stream:
try:
yaml.dump(loaded, stream, default_flow_style=False)
except yaml.YAMLError as exc:
print(exc)
So you just load the yaml into a dict
called loaded
, you modify the values you need then you save it (overwriting the original file or not, your call). For a nested input you'd have a nested dict you'd have to modify. The default_flow_style=False
parameter is necessary to produce the format you want (flow style), otherwise for nested collections it produces block style:
A: a
B: {C: c, D: d, E: e}
Cheers!
Later edit:
As Anthon pointed out, my answer has some flaws.
It's better to use safe_load
instead of load
since the later is potentially dangerous.
The output needs an directive end indicator (those three dashes at the beginning). To append them, we use explicit_start=True
in the dump
method (that should actually be safe_dump
).
Use maybe ruamel.yaml
instead of yaml
, if you want to generate a better output (although they are semantically the same)
See Anthon's answer for a more detailed information, since he's the author of the package.