【问题标题】:How to delete all comments in ruamel.yaml?如何删除 ruamel.yaml 中的所有评论?
【发布时间】:2020-02-05 16:40:00
【问题描述】:

默认情况下,ruamel.yaml 会保留所有 cmets。如何禁用此选项?我想从一个yaml文件中删除所有的cmets,这些cmets可以在任何地方。

目前我检查每个元素并设置yamldata.ca._items = {},但它并不总是有效。有时它只是在一行之前删除 cmets 而不是在之后。此外,它仅适用于第一级,要删除子图中的 cmets,我必须使用递归函数。

有什么简单的方法可以删除所有的 cmets 吗?

pyyaml 库不保留 cmets,但它也不允许配置缩进并且不保留顺序。 从文件中删除所有带有# 的行也会删除像key: value # comment 这样的行。

【问题讨论】:

  • 在 SO 上发帖时,您应该包含最少的工作代码,包括 yamldata.ca._items = {} 周围显示您的问题的部分

标签: python yaml ruamel.yaml


【解决方案1】:

如果您关心键的顺序,并且还没有使用 Python 2(您不应该), 然后你可以使用安全加载器加载然后使用(默认)往返转储器转储:

import sys
import ruamel.yaml

yaml_str = """\
x: # first mapping
   b: 1
   a: 2
y:
   - 3
   - "4" # last_item
"""

yaml = ruamel.yaml.YAML()
yaml.indent(mapping=4, sequence=4, offset=2)
yaml.preserve_quotes = True
yaml.default_flow_style = False

data = ruamel.yaml.YAML(typ='safe').load(yaml_str)
yaml.dump(data, sys.stdout)

给出:

x:
    b: 1
    a: 2
y:
  - 3
  - '4'

正如您所见,4 周围的引号已更改。

如果这是不可接受的,您应该使用往返加载程序加载, 和你一样,但只删除评论属性items, 您应该完全删除包含 cmets 的属性。

这当然不能使用 ca 属性来完成,你必须 删除属性本身。如果没有评论,你实际上 在所有没有的复杂节点上创建一个空的注释结构 在它们上使用.ca 时。

def recursive_delete_comment_attribs(d):
    if isinstance(d, dict):
        for k, v in d.items():
            recursive_delete_comment_attribs(k)
            recursive_delete_comment_attribs(v)
    elif isinstance(d, list):
        for elem in d:
            recursive_delete_comment_attribs(elem)
    try:
         # literal scalarstring might have comment associated with them
         attr = 'comment' if isinstance(d, ruamel.yaml.scalarstring.ScalarString) \
                  else ruamel.yaml.comments.Comment.attrib 
         delattr(d, attr)
    except AttributeError:
        pass



data = yaml.load(yaml_str)
recursive_delete_comment_attribs(data)
yaml.dump(data, sys.stdout)

给出:

x:
    b: 1
    a: 2
y:
  - 3
  - "4"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    • 1970-01-01
    • 2021-06-05
    • 2022-01-24
    • 1970-01-01
    • 2011-08-19
    • 2023-02-12
    相关资源
    最近更新 更多