使用 Python 在 YAML 中混合块格式和流格式

Mixing block and flow formatting in YAML with Python

我正在尝试使用 Python 和 pyyaml 更改深入嵌套在 YAML 文件中的值。我需要保留格式,这是块和流的组合。

我想更改嵌套在结构深层的字典中的单个值。例如,我可能会将 x 值更改为 2:

a:
    b:
        c: {x:1, y:1}
        d: {r1: 2, r2: 4}
        e:
            f: 1
            g: 1

我已经能够使用块格式或默认格式导入数据、更改值和转储文件,但两者都不完全符合我需要的格式。有没有办法混合格式或仅更改目标值而不重写整个文件?

您可能应该超越 PyYAML,问题之一是它将您的 {x:1, y:1} 构造为 Python dict {"x": 1, "y": 1},而它应该构造为 {"x:1": None, "y:1": None} ,因为冒号后没有 space 并且标量没有被双引号括起来。

假设您想要第一个 Python 表示,即使您不想将 YAML 更改为正确并依赖于 PyYAML 对其的错误解释,PyYAML 也不会在没有额外 space 在冒号之后,从而改变你的文件。

我建议您查看 ruamel.yaml(免责声明:我是该软件包的作者),除了更正输入的 YAML 之外,您唯一需要做的就是将映射的缩进设置为 4(如默认为 2).

ruamel.yaml 还支持在块样式下具有嵌套流样式节点,其中 PyYAML 仅支持全流(default-flow-style=True)、全块(default-flow-style=False)或全块- with-collection-leaf-nodes-flow(默认)开箱即用

import sys
import ruamel.yaml

yaml_str = """\
a:
    b:
        c: {x: 1, y: 1}  # these need spaces after the colon
        d: {r1: 2, r2: {r3: 3, r4: 4}}
        e:
            f: 1
            g: 1
"""

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=4)
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

给出:

a:
    b:
        c: {x: 1, y: 1}  # these need spaces after the colon
        d: {r1: 2, r2: {r3: 3, r4: 4}}
        e:
            f: 1
            g: 1

是的,评论也被保留了。