我正在使用Ruamel来保留人工编辑的YAML文件中的引用样式。
我的示例输入数据为:
---
a: '1'
b: "2"
c: 3
我使用以下方式读取数据:
def read_file(f):
with open(f, 'r') as _f:
return ruamel.yaml.round_trip_load(_f.read(), preserve_quotes=True)
然后我编辑了这些数据:
data = read_file('in.yaml')
data['foo'] = 'bar'
我使用以下方法写回磁盘:
def write_file(f, data):
with open(f, 'w') as _f:
_f.write(ruamel.yaml.dump(data, Dumper=ruamel.yaml.RoundTripDumper, width=1024))
write_file('out.yaml', data)
输出文件是:
a: '1'
b: "2"
c: 3
foo: bar
有没有办法可以强制引用字符串'bar',而不会在整个文件的其余部分强制执行引用样式?
(另外,我可以阻止它删除三个短划线---
?)
答案 0 :(得分:6)
为了保留字符串标量的引号(和文字块样式),ruamel.yaml¹-在往返模式中 - 将这些标量表示为SingleQuotedScalarString
,DoubleQuotedScalarString
和PreservedScalarString
。这些非常薄的包装器的类定义可以在scalarstring.py
中找到。
当序列化这样的实例时,“当它们被读取时”被写入,尽管有时候代表在事情变得困难时会回到双引号,因为它可以代表任何字符串。
要在添加新键值对时(或更新现有对)时出现此行为,您只需自己创建这些实例:
import sys
import ruamel.yaml
from ruamel.yaml.scalarstring import SingleQuotedScalarString, DoubleQuotedScalarString
yaml_str = """\
---
a: '1'
b: "2"
c: 3
"""
data = ruamel.yaml.round_trip_load(yaml_str, preserve_quotes=True)
data['foo'] = SingleQuotedScalarString('bar')
data.yaml_add_eol_comment('# <- single quotes added', 'foo', column=20)
ruamel.yaml.round_trip_dump(data, sys.stdout, explicit_start=True)
给出:
---
a: '1'
b: "2"
c: 3
foo: 'bar' # <- single quotes added
explicit_start=True
重新创建(多余的)文档开始标记。这样的标记是否在原始文件中并不是顶级字典对象“已知”,因此您必须手动重新添加它。
请注意,如果没有preserve_quotes
,则值1
和2
周围会有(单个)引号,以确保它们被视为字符串标量而不是整数。< / p>
¹其中我是作者。
答案 1 :(得分:2)
从Ruamel 0.15开始,将preserve_quotes标志设置为:
from ruamel.yaml import YAML
from pathlib import Path
yaml = YAML(typ='rt') # Round trip loading and dumping
yaml.preserve_quotes = True
data = yaml.load(Path("in.yaml"))
yaml.dump(data, Path("out.yaml"))