如何将周围的评论添加到列表中的元素

how to add surrounding comments to an element in a list

fruits = CommentedSeq()
fruits.append('banana')
fruits.yaml_set_comment_before_after_key(0, 'comments above', after='comments below')
yaml.dump({'fruits': fruits}, sys.stdout)

我希望输出如下:

fruits:
  # comments above
  - banana
  # comments below

但是根据我的测试,comments below 被丢弃了。

您使用的(未记录的)方法称为 yaml_set_comment_before_or_after_key。那 最后一部分 key 指的是映射中 key-value 对的 key。您正在使用序列 尽管在 round-trip 上处理两者有一些相似之处,但它们的处理方式不同。

在这种情况下,首先要做的是查看您是否想要 round-trip 的结果:

import sys
import ruamel.yaml

yaml_str = """\
fruits:
  # comments above
  - banana
  # comments below
"""

yaml = ruamel.yaml.YAML()
yaml.indent(sequence=4, offset=2)
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

这给出:

fruits:
  # comments above
  - banana
  # comments below

确实如此 round-trip。

然后将附加到加载数据的注释与您构建的数据进行比较:

from ruamel.yaml.comments import CommentedSeq

fruits = CommentedSeq()
fruits.append('banana')
fruits.yaml_set_comment_before_after_key(0, 'comments above', after='comments below')

print('loaded:   ', data['fruits'].ca)
print('generated:', fruits.ca)

不一样:

loaded:    Comment(comment=[None, [CommentToken('# comments above\n', line: 1, col: 2)]],
  items={0: [CommentToken('\n  # comments below\n', line: 3, col: 2), None, None, None]})
generated: Comment(comment=None,
  items={0: [None, [CommentToken('# comments above\n', col: 0)], None, [CommentToken('# comments below\n', col: 2)]]})

加载的数据没有 comments above 与序列元素 0 关联。它是注释 在序列开始之前存在。你仍然可以得到你想要的:

from ruamel.yaml.tokens import CommentToken
from ruamel.yaml.error import CommentMark

indent = 2
fruits.ca.comment = [None, [CommentToken('# comments above\n', CommentMark(indent))]]
fruits.ca.items[0] = [CommentToken(f'\n{" "*indent}# comments below\n', CommentMark(0)), None, None, None]
yaml.dump({'fruits': fruits}, sys.stdout)

给出:

fruits:
  # comments above
  - banana
  # comments below

请确保在使用时为您的应用程序固定 ruamel.yaml 版本 这些内部结构会发生变化。