【问题标题】:How do I update this yaml file with python and ruamel?如何使用 python 和 ruamel 更新这个 yaml 文件?
【发布时间】:2021-05-02 21:17:12
【问题描述】:

我有一个包含以下内容的 test.yaml 文件:

school_ids:
  school1: "001"

  #important school2
  school2: "002"


targets:
  neighborhood1:
    schools:
      - school1-paloalto
    teachers:
      - 33
  neighborhood2:
    schools:
      - school2-paloalto
    teachers:
      - 35

我想使用 ruamel 将文件更新为如下所示:

school_ids:
  school1: "001"

  #important school2
  school2: "002"

  school3: "003"


targets:
  neighborhood1:
    schools:
      - school1-paloalto
    teachers:
      - 33
  neighborhood2:
    schools:
      - school2-paloalto
    teachers:
      - 35
  neighborhood3:
    schools:
      - school3-paloalto
    teachers:
      - 31

如何使用 ruamel 更新文件以通过保留 cmets 来获得所需的输出?

这是我目前所拥有的:

import sys
from ruamel.yaml import YAML

inp = open('/targets.yaml', 'r').read()

yaml = YAML()

code = yaml.load(inp)
account_ids = code['school_ids']
account_ids['new_school'] = "003"
#yaml.dump(account_ids, sys.stdout)


targets = code['targets']
new_target = dict(neighborhood3=dict(schools=["school3-paloalto"], teachers=["31"]))
yaml = YAML()
yaml.indent(mapping=2, sequence=3, offset=2)
yaml.dump(new_target, sys.stdout)

【问题讨论】:

    标签: python file yaml pyyaml ruamel.yaml


    【解决方案1】:

    您只是在转储您从头开始创建的new_target,而不是使用code 甚至targets。 相反,您应该使用code 您加载并扩展了与其根级别键关联的值,然后转储 code

    import sys
    from pathlib import Path
    from ruamel.yaml import YAML
    
    inp = Path('test.yaml')
    
    yaml = YAML()
    
    code = yaml.load(inp)
    school_ids = code['school_ids']
    school_ids['school3'] = "003"
    
    
    targets = code['targets']
    targets['neighborhood3'] = dict(schools=["school3-paloalto"], teachers=["31"])
    yaml = YAML()
    yaml.indent(mapping=2, sequence=4, offset=2)
    yaml.dump(code, sys.stdout)
    

    给出:

    school_ids:
      school1: '001'
    
      #important school2
      school2: '002'
    
    
      school3: '003'
    targets:
      neighborhood1:
        schools:
          - school1-paloalto
        teachers:
          - 33
      neighborhood2:
        schools:
          - school2-paloalto
        teachers:
          - 35
      neighborhood3:
        schools:
          - school3-paloalto
        teachers:
          - '31'
    

    请注意,您的序列缩进至少需要比您的 偏移量(2 个位置为- + SPACE 留出空间)

    输出在键 school2 之后之间有空行,因为那是 这些在解析期间关联。这可以移动到新键,但是 这不是微不足道的。如果你需要这样做(这对语义并不重要 YAML 文档),然后看看我的回答 here

    【讨论】:

    • 感谢您的及时回复@Anthon。我注意到,在我在您的回复中也遵循的示例中,我们正在 sys.stdout 中打印。有没有办法更新同一个文件并将更新的字段和值写入其中?使用相同的 ruamel 模块。 Baically 更新文件...提前谢谢你!!!
    • @Becks 如果您使用pathlib.Path 实例(就像我一样),写回文件就像yaml.dump(code, inp) 一样简单。相应的会为您打开和关闭文件。如果输出应该转到不同的文件,则创建一个新的Path(或者如果您需要保留旧文件内容,请考虑重命名inp
    猜你喜欢
    • 2019-09-08
    • 2020-05-23
    • 2016-09-26
    • 2015-04-17
    • 1970-01-01
    • 2017-01-03
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多