python ruamel.yaml 包,如何获取标题注释行?

Posted

技术标签:

【中文标题】python ruamel.yaml 包,如何获取标题注释行?【英文标题】:python ruamel.yaml package, how to get header comment lines? 【发布时间】:2022-01-14 01:25:59 【问题描述】:

我想在标题行获取 YAML 文件 cmets,例如

# 11111111111111111
# 11111111111111111
# 22222222222222222
# bbbbbbbbbbbbbbbbb
---
start:
....

我在加载的数据上使用了ca属性,但发现上面没有这些cmets。有没有其他方法可以获得这些cmets?

【问题讨论】:

我希望 YAML 解析器忽略 cmets。因此,您可以以传统方式打开文件,然后检查第一个重要字符是否为 #。如果您想提取遵循正常 YAML 语法的 cmets,这将更加复杂 - 例如,“start: # This is the start” @JCaesar ruamel.yaml (discl。我是作者)明确尝试将 cmets 保留在其往返模式中,因为对于必须继续工作的人来说,这通常是一种损失在(也)由计算机程序加载和转储的 YAML 文档上。 谢谢大家,我正在考虑用传统方式获取这些cmets,然后插入到其他yaml文件中。 【参考方案1】:

当前 (ruamel.yaml==0.17.17) 发生的 cmets 在文档开始令牌 (---) 未从 DocumentStartTokenDocumentStartEvent,所以这些 cmets 是 在解析过程中有效丢失。即使他们被传递,它是 保存它们并非易事,因为DocumentStartEvent 是默默地 在作曲过程中掉线。

您可以将 cmets 放在指令指示符的结尾之后 (---),它允许您使用 .ca 访问 cmets 属性没有问题,或完全删除该指标,因为它 是多余的(至少在你的例子中)。或者,您将不得不 在加载器周围写一个小包装器:

import sys
import pathlib
import ruamel.yaml

fn = pathlib.Path('input.yaml')

def load_with_pre_directives_comments(yaml, path):
    comments = []
    text = path.read_text()
    if '\n---\n' not in text and '\n--- ' not in text:
         return yaml.load(text), comments
    for line in text.splitlines(True):
        if line.lstrip().startswith('#'):
            comments.append(line)
        elif line.startswith('---'):
            return yaml.load(text), comments
            break

yaml = ruamel.yaml.YAML()
yaml.explicit_start = True
data, comments = load_with_pre_directives_comments(yaml, fn)
print(''.join(comments), end='')
yaml.dump(data, sys.stdout)

给出:

# 11111111111111111
# 11111111111111111
# 22222222222222222
# bbbbbbbbbbbbbbbbb
---
start: 42

【讨论】:

以上是关于python ruamel.yaml 包,如何获取标题注释行?的主要内容,如果未能解决你的问题,请参考以下文章

Python之ruamel.yaml模块详解| ruamel.yaml与pyyaml的区别

Python之ruamel.yaml模块详解

Python之ruamel.yaml模块详解

通过 ruamel.yaml 转储时如何在 yaml 文件中保留空值

如何配置 ruamel.yaml.dump 输出?

如何使用显式引用转储 YAML?