【问题标题】:Dynamically modify yaml and preserve all formatting and comments - python动态修改yaml并保留所有格式和注释-python
【发布时间】:2020-02-07 04:26:09
【问题描述】:

我有一个像这样的config.yml 文件:

# CONFIGURATION FILE
# COMMENT 1 blah 
# COMMENT 2 blah blah
# COMMENT 3 blah blah blah

NAME: Fruits

# CONFIGURATION FILE
# COMMENT 4 blah 
# COMMENT 5 blah blah
# COMMENT 6 blah blah blah

fruit_list:
  - "apple-01:9100"

我想动态修改fruit_list。我想从烧瓶网络表单中附加用户输入的数据。下面是我试过的代码,我只能用这个代码修改和附加一个字符串。

import ruamel.yaml
from ruamel.yaml import YAML

yaml = YAML()
conf_file = pathlib.Path('configs/config.yml')
conf_key = yaml.load(conf_file)
conf_key['Fruits'] = form.bsa.data
conf_key['fruit_list'] = form.fqdn.data + ':9100'
yaml.dump(conf_key, conf_file)

上面的代码只允许我修改/追加一个字符串到fruit_list。此外,它不保留格式。注释被保留,但间距是一团糟,并且不断增加空间。请参阅下面的输出:

# CONFIGURATION FILE

# COMMENT 1 blah 

# COMMENT 2 blah blah

# COMMENT 3 blah blah blah

NAME: Fruits

# CONFIGURATION FILE
# COMMENT 4 blah 
# COMMENT 5 blah blah
# COMMENT 6 blah blah blah

fruit_list: apple-01:9100

所需的输出如下:

# CONFIGURATION FILE
# COMMENT 1 blah 
# COMMENT 2 blah blah
# COMMENT 3 blah blah blah

NAME: Fruits

# CONFIGURATION FILE
# COMMENT 4 blah 
# COMMENT 5 blah blah
# COMMENT 6 blah blah blah

fruit_list:
  - "apple-01:9100"
  - "orange-01:9100"
  - "pear-01:9100"
  - "grape-01:9100"

我还希望fruit_list 中的附加内容根据用户输入的fruits 数量是动态的。

【问题讨论】:

    标签: python yaml ruamel.yaml


    【解决方案1】:

    我认为您的 YAML 输入有问题(除了使用 .yml 扩展名,自 2006 年起为 recommended extension for YAML files has been .yaml )。我怀疑你的输入有一些额外的回车或其他一些东西, 所以请确保您通过print(repr(conf_key)) 和可能的方式进行检查

    conf_key = conf_key.replace('\r', '\n')
    

    或类似的清理东西。如下所示,我无法重现获得额外的换行符

    至于附加到 YAML 序列,如果你想你必须附加到 Python 中的对应列表。并且不为键分配新的非列表值 父字典:

    import sys
    import pathlib
    import ruamel.yaml
    
    conf_file = pathlib.Path('config.yaml')
    
    
    conf_file.write_text("""\
    # CONFIGURATION FILE
    # COMMENT 1 blah 
    # COMMENT 2 blah blah
    # COMMENT 3 blah blah blah
    
    NAME: Fruits
    
    # CONFIGURATION FILE
    # COMMENT 4 blah 
    # COMMENT 5 blah blah
    # COMMENT 6 blah blah blah
    
    fruit_list:
      - "apple-01:9100"
    """)
    
    yaml = ruamel.yaml.YAML()
    yaml.indent(sequence=4, offset=2)
    conf_key = yaml.load(conf_file)
    conf_key['Fruits'] = 'some_data'
    conf_key['fruit_list'].append('orange-01:9100')
    conf_key['fruit_list'].extend(['pear-01:9100', 'grape-01:9100'])
    yaml.dump(conf_key, sys.stdout)
    

    给出:

    # CONFIGURATION FILE
    # COMMENT 1 blah 
    # COMMENT 2 blah blah
    # COMMENT 3 blah blah blah
    
    NAME: Fruits
    
    # CONFIGURATION FILE
    # COMMENT 4 blah 
    # COMMENT 5 blah blah
    # COMMENT 6 blah blah blah
    
    fruit_list:
      - apple-01:9100
      - orange-01:9100
      - pear-01:9100
      - grape-01:9100
    Fruits: some_data
    

    使用您的代码,您还应该在根级映射中期待一个额外的键 Fruits

    一般来说最好 在测试时写入不同的文件或标准输出:无需恢复您的原始输入。

    【讨论】:

    • 谢谢@Anthon。我会努力回来的。
    猜你喜欢
    • 2018-05-03
    • 2018-09-23
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 2019-09-04
    • 1970-01-01
    • 2014-08-13
    • 2021-11-02
    相关资源
    最近更新 更多