保留引号,并在Ruamel中添加带引号的数据

时间:2016-09-01 04:06:34

标签: python ruamel.yaml

我正在使用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',而不会在整个文件的其余部分强制执行引用样式?

(另外,我可以阻止它删除三个短划线---?)

2 个答案:

答案 0 :(得分:6)

为了保留字符串标量的引号(和文字块样式),ruamel.yaml¹-在往返模式中 - 将这些标量表示为SingleQuotedScalarStringDoubleQuotedScalarStringPreservedScalarString 。这些非常薄的包装器的类定义可以在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,则值12周围会有(单个)引号,以确保它们被视为字符串标量而不是整数。< / 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"))