Python 在数组后保留注释
这就是我的YAML的样子:Python 在数组后保留注释,python,ruamel.yaml,Python,Ruamel.yaml,这就是我的YAML的样子: yaml_str = """\ steps: - init - run - cleanup # This is a comment which needs to be preserved """ 我想做的是从步骤中删除第一个和最后一个项目,同时保留清理后的注释。即,输出需要如下所示: yaml_str = """\ steps: - run # This is a comment which needs to be preserved """
yaml_str = """\
steps:
- init
- run
- cleanup
# This is a comment which needs to be preserved
"""
我想做的是从步骤中删除第一个和最后一个项目,同时保留清理后的注释。即,输出需要如下所示:
yaml_str = """\
steps:
- run
# This is a comment which needs to be preserved
"""
如何使用ruamel.yaml实现这一点
另外,据我所知,就API而言,情况与此不同:
,如果我错了,请纠正我 好的,看起来我需要使用这个结构:
已解析['steps'].ca.items[1]=已解析['steps'].ca.items.pop(2)
好的,看起来我需要使用这个结构:
已解析['steps'].ca.items[1]=已解析['steps'].ca.items.pop(2)
从YAML文件加载数据时,ruamel.YAML
通常会附加
对正在扫描的最新集合的注释,基于密钥(在
映射的大小写)或索引(序列)
因此,在您的例子中,注释(以及行的空头和空行
在它之前)附加到序列(而不是根级别
映射)
注释当前存储在属性ca
(commentattribute)中。
因此,对于您的示例,您可以:
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
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
如果从序列中删除单个项,则会删除类似字典的对象
(CommentedSeq
)足够聪明,可以“移动”注释。(你可以
在删除之前和之间插入print(data['steps'].ca)
,以查看此信息
已发生)
这并不总是有效的,尤其是当您的
序列是一个集合。在这种情况下,您需要将注释移动到最后
该集合的元素。如果该项是序列/列表,则只需移动注释即可
但是,如果是映射/dict,则需要重新安排内容,以避免
注释出现在键和值之间:
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)
其中:
steps:
- run
# This is a comment which needs to be preserved
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)。从YAML文件加载数据时,ruamel.YAML
通常会附加
对正在扫描的最新集合的注释,基于密钥(在
映射的大小写)或索引(序列)
因此,在您的例子中,注释(以及行的空头和空行
在它之前)附加到序列(而不是根级别
映射)
注释当前存储在属性ca
(commentattribute)中。
因此,对于您的示例,您可以:
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
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
如果从序列中删除单个项,则会删除类似字典的对象
(CommentedSeq
)足够聪明,可以“移动”注释。(你可以
在删除之前和之间插入print(data['steps'].ca)
,以查看此信息
已发生)
这并不总是有效的,尤其是当您的
序列是一个集合。在这种情况下,您需要将注释移动到最后
该集合的元素。如果该项是序列/列表,则只需移动注释即可
但是,如果是映射/dict,则需要重新安排内容,以避免
注释出现在键和值之间:
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)
其中:
steps:
- run
# This is a comment which needs to be preserved
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)。是的,这看起来是正确的。注释与它们后面的项目相关联,行尾注释被视为以空行和仅进一步注释的行继续。我会使用parsed['steps'].ca.items[-2]=parsed['steps'].ca.items.pop(-1)
将最后一项上的注释移动到之前的注释。谢谢@Anthon。我现在面临的唯一问题是一个数组,其中一个元素(中间一个)是映射(其他元素只是字符串)。希望也能解决。干杯,看起来不错。注释与它们后面的项目相关联,行尾注释被视为以空行和仅进一步注释的行继续。我会使用parsed['steps'].ca.items[-2]=parsed['steps'].ca.items.pop(-1)
将最后一项上的注释移动到之前的注释。谢谢@Anthon。我现在面临的唯一问题是一个数组,其中一个元素(中间一个)是映射(其他元素只是字符串)。希望也能解决。干杯