如何使用 ruamel.yaml 的往返正确设置 YAML 流式转储?
How to properly set up YAML flow style dumping using round-trip with ruamel.yaml?
我正在使用 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
您似乎没有做错任何事,但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)
我正在使用 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
您似乎没有做错任何事,但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)