Search code examples
pythonyamlpyyaml

Python: Replacing a String in a YAML file


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.


Solution

  • 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.