【问题标题】:python3 - edit value in YAML file in placepython3 - 在 YAML 文件中编辑值
【发布时间】:2017-01-19 09:39:08
【问题描述】:

我正在尝试使用 PyYAML 和 Python3 来编辑 YAML 文件中的值(这是一个 Hiera 数据结构,但这有点离题了)。

使用yaml.safe_loadyaml.dump 很容易实现。我遇到的问题是我需要保留 cmets、空格、排序和其他格式。也就是说,当我编辑给定键的值时,这应该是文件中的 only 更改。 (不需要自己添加或删除密钥。)

就我而言,这些是二级密钥。我可以使用正则表达式或某种形式的状态机来做到这一点——但这很讨厌。有没有人知道一个图书馆已经很好地做到了这一点?

这是一个有关 YAML 的虚拟示例:

---
# Some form of comment block.
# Some form of comment block.
# Some form of comment block.

# This is my config block.
config::me:
  key0: 123
  key1: 456

# This is another config block:
applications:
  frontend:
    version: '2.4.2'
    enabled: true
  backend:
    version: '4.3.9'
    enabled: false

# More comments etcetera.

基本上我需要做的是定位applications.frontent.version并将值从2.4.2更新为2.4.3,而无需触及文件中的任何内容

【问题讨论】:

    标签: python yaml


    【解决方案1】:

    您可以为此使用 ruamel.yaml,它是 PyYAML ¹ 的派生词。它是专门为执行这种往返、保留 cmets 和原始文件中的其他一些事情而创建的,大多数解析器在往返期间会丢弃这些内容(它也与 YAML 1.2 兼容,而 PyYAML 支持 1.1)

    import sys
    import ruamel.yaml
    from ruamel.yaml.util import load_yaml_guess_indent
    from ruamel.yaml.scalarstring import SingleQuotedScalarString
    
    ys = """\
    ---
    # Some form of comment block.
    # Some form of comment block.
    # Some form of comment block.
    
    # This is my config block.
    config::me:
      key0: 123
      key1: 456
    
    # This is another config block:
    applications:
      frontend:
        version: '2.4.2'
        enabled: true
      backend:
        version: '4.3.9'
        enabled: false
    
    # More comments etcetera.
    """
    
    data, indent, block_seq_indent = load_yaml_guess_indent(ys, preserve_quotes=True)
    data['applications']['frontend']['version'] = SingleQuotedScalarString('2.4.3')
    ruamel.yaml.round_trip_dump(data, sys.stdout, explicit_start=True)
    

    给你:

    ---
    # Some form of comment block.
    # Some form of comment block.
    # Some form of comment block.
    
    # This is my config block.
    config::me:
      key0: 123
      key1: 456
    
    # This is another config block:
    applications:
      frontend:
        version: '2.4.3'
        enabled: true
      backend:
        version: '4.3.9'
        enabled: false
    
    # More comments etcetera.
    

    preserve_quotes 选项和 SingleQuotedScalarString() 的使用是必需的,因为标量 2.4.34.3.9 周围有引号,这些引号是多余的,通常会被删除。


    ¹ 免责声明:我是ruamel.yaml的作者。

    【讨论】:

    • 哦哦。我真的看过那个。但我并没有完全相信它会如此逐字记录。我会尽快查看并报告! FWIW,标量周围的引号是因为我们还有格式为 201612012359 的版本号,如果没有引用,最终会被 Puppet 转换为 int 。所以最简单的方法就是给人们一个一致的方向。
    • 嗯,你真是太棒了。我们就这样吧!感谢您的帮助(和图书馆)。
    猜你喜欢
    • 2021-07-27
    • 2016-08-25
    • 2018-12-19
    • 2015-06-13
    • 2020-12-14
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多