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

时间:2018-08-22 22:44:26

标签: python yaml pyyaml

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

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

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

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

1 个答案:

答案 0 :(得分:0)

您可能应该超越PyYAML,问题之一是它将{x:1, y:1}构造为Python dict {"x": 1, "y": 1},应该将其构造为{"x:1": None, "y:1": None},因为没有空间冒号和标量后不加双引号。

假设您想要第一个Python表示形式,即使您不希望将YAML更改为正确的,而是依靠PyYAML对它的错误解释,PyYAML也不会在没有冒号后的多余空间的情况下转储它,从而更改了您的文件。

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

ruamel.yaml还支持在块样式下具有嵌套的流样式节点,其中PyYAML仅支持全流(default-flow-style=True),全块(default-flow-style=False)或全块收集-开箱即用的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

是的,评论也会保留。