这是我的YAML外观:
yaml_str = """\
steps:
- init
- run
- cleanup
# This is a comment which needs to be preserved
"""
我想做的是从steps
中删除第一个和最后一个项目,同时保留cleanup
之后的注释。即输出需要是这样的:
yaml_str = """\
steps:
- run
# This is a comment which needs to be preserved
"""
使用ruamel.yaml怎么可能?
P.S。据我了解,就API而言,情况并不完全相同: https://stackoverflow.com/a/57585928/896276,如果我错了,请纠正我。
答案 0 :(得分:2)
好的,看来我需要使用此构造:
parsed ['steps']。ca.items [1] =解析的['steps']。ca.items.pop(2)
答案 1 :(得分:0)
从YAML文件加载数据时,ruamel.yaml
通常会附加
根据密钥(在
映射)或索引(序列)。
因此,在您的情况下,注释(以及空行尾和空行 之前)附加到序列(而不是根级别) 映射)。
注释当前存储在属性ca
中( c 注释 a 属性)。
因此,对于您的示例,您可以执行以下操作:
import sys
import ruamel.yaml
yaml_str = """\
steps:
- init
- run
- cleanup
# This is a comment which needs to be preserved
"""
yaml = ruamel.yaml.YAML()
yaml.indent(sequence=4, offset=2)
yaml.preserve_quotes = True
data = yaml.load(yaml_str)
steps = data['steps']
del steps[0]
steps.pop(-1)
yaml.dump(data, sys.stdout)
给出:
steps:
- run
# This is a comment which needs to be preserved
如果您从序列中删除单个项目,则字典类对象
(CommentedSeq
)很聪明,可以“移动”评论。 (您可以
在删除之前和之间插入print(data['steps'].ca)
以查看此内容
发生了。)
这并不总是有效,特别是当您的第二个元素 序列是一个集合。在这种情况下,您需要自己将评论移到最后 该集合的元素。如果该项目是序列/列表,则只需移动注释即可 但是,如果是映射/字典,则需要重新安排内容以免 注释出现在键和值之间:
import sys
import ruamel.yaml
yaml_str = """\
steps:
- init
- a: 42
b: 39
- - 196
- 3.0
- cleanup
# This is a comment which needs to be preserved
"""
yaml = ruamel.yaml.YAML()
yaml.indent(sequence=4, offset=2)
yaml.preserve_quotes = True
data = yaml.load(yaml_str)
steps = data['steps']
print(steps.ca)
del steps[2] # you can comment this out to get the comment attached to 3.0
if isinstance(steps, list):
if len(steps)-1 in steps.ca.items and len(steps) > 1 and isinstance(steps[-2], (list, dict)):
# move the comment in advance
tmp = steps[-2]
ct = steps.ca.items.pop(len(steps)-1)
if isinstance(tmp, list):
key_tmp = len(tmp)-1
else:
key_tmp = list(tmp.keys())[-1] # the final mapping key
ct[0], ct[2] = None, ct[0]
tmp.ca.items[key_tmp] = ct
del steps[0]
steps.pop(-1)
yaml.dump(data, sys.stdout)
给出:
Comment(comment=None,
items={3: [CommentToken('\n\n# This is a comment which needs to be preserved\n', line: 8, col: 0), None, None, None]})
steps:
- a: 42
b: 39
# This is a comment which needs to be preserved
请把您的代码固定在您测试过的ruamel.yaml版本上。这些内部因素可以而且会 有所改变(希望他们这样做时使用适当的API)。