如何使用ruamel.YAML往返正确设置YAML流式倾倒?

2024-05-20 02:03:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用ruamel.yaml包,但似乎无法以格式良好的流样式将其输出。我想让元素保持在同一级别上,并用尾随的逗号和换行符分隔。我还想保留每一条评论,似乎有些评论在转换成流风格后就消失了。以下是一个例子:

原始

background_opacity: 0.9 # comment
cursor: {style: Beam}

# comment
font:
    normal: {family: Fira Code, style: Retina} # comment
    size: 12.0 # comment

预期

{
    background_opacity: 0.9, # comment
    cursor: {style: Beam},
    
    # comment
    font: {
        normal: {family: Fira Code, style: Retina}, # comment
        size: 12.0 # comment
    }
}

实际

{background_opacity: 0.9 # comment
, cursor: {style: Beam}, font: {normal: {family: Fira Code, style: Retina} # comment
, size: 12.0   # comment
}}

我的代码附在下面。我是YAML和ruamel.YAML的新手,所以我为任何简单的错误道歉

from ruamel.yaml import YAML

def round_trip(sout, sin, idt):
    yaml = YAML()
    assert idt >= 2
    yaml.indent(mapping=idt, sequence=idt, offset=idt-2)
    yaml.preserve_quotes = True

    data = yaml.load(sin)
    if data is not None:
        data.fa.set_flow_style() # needs fixing: commas are not trailing
        yaml.dump(data, sout)
    else:
        print("the file is empty") # needs fixing: should dump original file

Tags: yamldatastylecommentruamelfamilycursorbeam
1条回答
网友
1楼 · 发布于 2024-05-20 02:03:55

您似乎没有做错任何事情,但是ruamel.yaml不支持生成这种输出。它只是试图在一行中填充尽可能多的流样式,而您得到的换行是因为输出注释(与它们前面的映射键关联)会强制这样的换行

如果您的输入没有任何注释,那么根据您设置的输出宽度,您将得到一行或两行

如果在加载时向每一行添加一个伪注释,并在转储后删除该注释,可能会得到稍微好一点的结果,但这仍然不会使您在自己的行上打开大括号

当前,您只设置根级别的样式属性,该属性“有效”,因为您没有嵌套的块样式集合。您应该使用以下方法递归执行此操作:

def set_style(d, flow):
    if isinstance(d, dict):
        if flow:
            d.fa.set_flow_style()
        else:
            d.fa.set_block_style()
        for k in d:
            set_style(d[k], flow)
    elif isinstance(d, list):
        if flow:
            d.fa.set_flow_style()
        else:
            d.fa.set_block_style()
        for item in d:
             set_style(item, flow)


data = yaml.load(sin)
set_style(data, flow=True)

相关问题 更多 >