首页 > 解决方案 > 使用 ruamel.yaml 解析 YAML 注释

问题描述

我正在尝试使用 ruamel.yaml 解析 yaml 文件的注释。问题是,我想以某种特定的方式解析评论(尽管我认为它是逻辑的)。我有以下 yaml 文件:

---
# comment for the foo variable
foo: 'foo_val'

# comment for the bar variable
bar: ['item1', 'item2']

我一直在尝试做的是以下几点:

from ruamel.yaml import YAML
yaml = YAML()
yaml.preserve_quotes = True
yaml.explicit_start = True

stream = open('my_file.yml', 'r')
loaded = yaml.load(stream) # by default is roundtrip

loaded.ca 
print(loaded)

打印以下内容:

Comment(
start=[None, [CommentToken('# comment for the foo variable\n', line: 1, col: 0)]],
items={
foo: [None, None, CommentToken('\n\n# comment for the bar variable\n', line: 3, col: 0), None]})

ordereddict([('foo', 'foo_val'), ('bar', ['item1', 'item2'])])

如您所见,注释地图(我相信它是这样称呼的)没有保持顺序。我尝试了另一种方式,在变量定义下方进行评论,但使用 Python 样式的列表也不起作用。

有谁知道是否可以在不将第一条评论视为该start对象的情况下获得评论地图?基本上,我的预期输出将是每个变量,评论就在顶部,即:

Comment(
    items={
    foo: [None, None, CommentToken('\n\n# comment for the foo variable\n', line: 0, col: 0), None],
    bar: [None, None, CommentToken('\n\n# comment for the bar variable\n', line: 3, col: 0), None],
  })

编辑

理想情况下,我需要保持我展示的示例中的格式,或者直接从一种格式转换为另一种格式。

标签: python-3.xyamlruamel.yaml

解决方案


YAML 规范要求丢弃注释。因此,它们的指定方式不能让您严格控制与它们关联的节点。

ruamel 尽最大努力将注释映射到它认为它们所属的位置,以便可以复制初始输入,但它通常不能在保留 YAML 语法的同时为您提供您所要求的控制。

一种可能的解决方案是使用显式键语法,以便您可以在键后面写注释,这将创建一个清晰的关联:

? foo # comment for the foo variable
: 'foo_val'
? bar # comment for the bar variable
: ['item1', 'item2']

经 Anthon 确认,目前无效的原始提案:

一个可能的解决方案是使用流映射,它有一个明确的开始,因此注释肯定在映射内部:

{
  # comment for the foo variable
  foo: 'foo_val',

  # comment for the bar variable
  bar: ['item1', 'item2']
}

'foo_val'请注意流语法所需的逗号。缩进是可选的。


推荐阅读