将 YAML 中的块和流格式与 Python 混合 [英] Mixing block and flow formatting in YAML with Python

查看:26
本文介绍了将 YAML 中的块和流格式与 Python 混合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to change a value nested deeply in a YAML file using Python and pyyaml. I need to preserve the formatting, which is a combination of block and flow.

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

I want to change a single value nested in a dictionary several layers deep in the structure. For example, I might change the x value to 2:

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

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

I've been able to import the data, change the value, and dump the file with block formatting or with default formatting, but neither exactly matches the format that I need. Is there a way to either mix the formatting or to only change the target value without re-writing the entire file?

推荐答案

你可能应该超越 PyYAML,问题之一是它构建你的 {x:1, y:1}Python dict {"x": 1, "y": 1} 应该构造为 {"x:1": None, "y:1": None},因为冒号后没有空格并且标量不是双引号.

You should probably look beyond PyYAML, one of the problems is that it constructs your {x:1, y:1} to the Python dict {"x": 1, "y": 1} where it should be construct to {"x:1": None, "y:1": None}, as there is no space after the colon and the scalars are not double quoted.

假设您想要第一个 Python 表示,即使您不想将 YAML 更改为正确并依赖 PyYAML 对其的错误解释,PyYAML 也不会在没有冒号后的额外空间的情况下转储它,从而改变您的文件.

Assuming you want the first Python representation, even if you rather not change your YAML to be correct and rely on the faulty interpretation thereof by PyYAML, PyYAML is not going to dump that without the extra space after the colon, thus changing your files.

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

I suggest you look at ruamel.yaml (disclaimer: I am the author of that package) where you only extra thing apart from correcting your input YAML, is to to set the indent for mappings to 4 (as the default is 2).

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

ruamel.yaml also supports having nested flow style nodes under block style where PyYAML only supports all-flow (default-flow-style=True), all-block (default-flow-style=False)or all-block-with-collection-leaf-nodes-flow (the default) out-of-the-box

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

是的,评论也被保留了.

And yes, the comment is preserved as well.

这篇关于将 YAML 中的块和流格式与 Python 混合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆