在PyYAML中保存/转储带注释的YAML文件

81 投票
5 回答
58810 浏览
提问于 2025-04-17 00:53

我有一个yaml文件,内容是这样的:

# The following key opens a door
key: value

有没有办法让我在加载保存这些数据的时候,保留里面的注释呢?

5 个回答

5

我有一个修改版的pyyaml,正好实现了这个功能。你可以在这里找到它:https://github.com/pflarr/pyyaml

要创建一个带注释的yaml文件,你需要生成一个事件流,这个流里要包含注释事件。目前,注释只能放在序列项和映射键的前面。

这个功能目前只适用于python3,我还没有把它移植到python2的版本,不过如果有人需要,我可以很快做到。此外,这个功能也应该很容易移植到C语言的libyaml,因为这个python代码其实就是对它的简单移植。

130

如果你在使用块结构的YAML文件,可以用一个叫做 ruamel.yaml 的Python包。这个包是PyYAML的一个衍生版本,它可以保留注释的原样

import sys
import ruamel.yaml

yaml_str = """\
# example
name:
  # details
  family: Smith   # very common
  given: Alice    # one of the siblings
"""

yaml = ruamel.yaml.YAML()  # defaults to round-trip if no parameters given
code = yaml.load(yaml_str)
code['name']['given'] = 'Bob'

yaml.dump(code, sys.stdout)

结果如下:

# example
name:
  # details
  family: Smith   # very common
  given: Bob      # one of the siblings

注意,行末的注释依然对齐。

这里用的不是普通的 listdict 对象,而是一些特别的版本²,注释是附加在这些版本上的。

¹ 安装方法是用 pip install ruamel.yaml。这个包支持Python 2.6/2.7/3.3及以上版本。
² 在映射的情况下,使用 ordereddict 来保持顺序。

34

PyYAML在很底层就把注释给丢掉了(在Scanner.scan_to_next_token这个地方)。

虽然你可以对它进行一些调整或者扩展,让它能处理整个过程中的注释,但这会是一个大改动。把注释输出(也就是显示出来)似乎要简单一些,这在旧的PyYAML问题追踪器上有讨论过,具体可以查看114号票据

截至2023年,关于添加加载注释支持的功能请求仍然没有进展。

撰写回答