我需要为YAML文件中的现有密钥添加额外的值。以下是我正在使用的代码。
with open(yaml_in_path, 'r') as f:
doc, ind, bsi = load_yaml_guess_indent(f, preserve_quotes=True)
doc['phase1'] += ['c']
with open(yaml_out_path, 'w') as f:
ruamel.yaml.round_trip_dump(doc, f,
indent=2, block_seq_indent=bsi)
这是输入和输出。
输入
phase1:
- a
# a comment.
- b
phase2:
- d
输出
phase1:
- a
# a comment.
- b
- c
phase2:
- d
如何摆脱b
和c
之间的新界限? (当phase1
是文件中的唯一键或phase1
和phase2
之间没有空行时,此问题不存在。)
答案 0 :(得分:0)
这里的问题是空行被认为是一种注释,ruamel.yaml
中的注释通过将它们与序列中的元素或映射中的键相关联来保留。该值存储在名为ca
的复杂属性中,类似于对象doc['phase1']
,与第二个元素关联。
你当然可以争辩说它应该与顶级映射/字典相关联,或者与键phase1
相关联(作为一些最终的空行注释),或者与phase2
相关联,因为它是一些介绍性的空直插式注释。
以上三者中的任何一个都是有效的,并且库中目前没有控制策略,其中空行(或注释)。
如果您输入“真实”评论(以#
开头),则将与phase1
关联作为结束评论,因为策略不同。
这显然需要彻底改革,因为ruamel.yaml
的最初目标是:
- 从YAML加载一些配置
- 改变一些价值
- 将配置保存到YAML
在这种情况下,这种追加/插入问题不会出现。
因此,在扩展库以及对附加(尾随)注释和/或空行的位置进行一些控制之前,没有真正的解决方案。
在实施此类控制之前,您可以做的最好的事情如下:
import sys
import ruamel.yaml
yaml_str = """\
phase1:
- a
# a comment.
- b
phase2:
- d
"""
def append_move_comment(l, e):
i = len(l) - 1
l.append(e)
x = l.ca.items[i][0] # the end comment
if x is None:
return
l.ca.items[i][0] = None
l.ca.items[i+1] = [x, None, None, None]
data = ruamel.yaml.round_trip_load(yaml_str)
append_move_comment(data['phase1'], 'c')
ruamel.yaml.round_trip_dump(data, sys.stdout, indent=4, block_seq_indent=2)
我将indent
值更改为4,这是您的输入所具有的(并且因为您将其指定为block_seq_indent的小值)。