python - 如何在 ruamel 中保留评论
问题描述
我需要对带有注释的 YAML 文件进行排序。我正在使用 ruamel.yaml 库来保留来自 YAML 的评论,但是当我对项目进行排序时,评论被放置在错误的位置。
people = """\
# manager of project
- title: manager
# owner of company
- title: owner
"""
import ruamel.yaml, sys
yaml = ruamel.yaml.YAML()
arr = yaml.load(people)
arr = sorted(arr, key=lambda x: x['title'])
yaml.dump(arr, sys.stdout)
使用此代码,我得到以下输出:
- title: manager
# owner of company
- title: owner
在排序期间,第一个元素的注释消失了。如何保留列表的第一条评论?
解决方案
Your first comment, at the beginning of the document, has no
preceeding node and gets a special place on the arr
object (which is
of type ruamel.yaml.comments.CommentedSeq
). You can inspect this by
doing print(arr.ca)
(ca for comment attribute), directly after
loading.
After loading there is a second comment attribute attached to the dict
like object constructed from the mapping arr[0]
and a third comment
attribute attached to a dict like object constructed from arr[1]
(in
much the same way as the first comment is attached to arr
).
The sorting operation is not done in place, hence only the
comments associated with the elements that are sorted stay put. The
arr
after the asignment (a simple list
), of the result of
sorted()
is not even the same type as the arr
loaded from YAML (a
CommentedSeq
), and of course has no comments associated with it.
So what you need to do is preserve the comment information, make the result of sorted of the appropriate type and then assign the preserved information to that object. Fortunately this only requires one changed and one added line to your code:
import sys
import ruamel.yaml
people = """\
# manager of project
- title: manager
# owner of company
- title: owner
"""
yaml = ruamel.yaml.YAML()
arr = yaml.load(people)
root_comment = arr.ca
arr = ruamel.yaml.comments.CommentedSeq(sorted(arr, key=lambda x: x['title']))
arr._yaml_comment = root_comment
yaml.dump(arr, sys.stdout)
which gives:
# manager of project
- title: manager
# owner of company
- title: owner
However in general this kind of extensive manipulation will get you into trouble. It is probably better to try doing this with an in-place sort.
推荐阅读
- c# - 绑定到 ObservableCollection 内对象的 ObservableCollection 属性
- javascript - 如何修复 googleappmaker 中的“未定义 DocumentApp”
- c# - 将 DataGridViewButtonCell 转换为类型 DataGridViewDisableButtonCell 时出错
- python - 嵌入在合并中的 for 循环
- mysql - MySql - 在某个单词之后选择一些字符并将其添加到另一列
- c++ - 如何找到数组左右两侧的最大元素?
- java - Spring DI 同时具有两个构造函数
- python - 使用 Python 发送 HTTP Post,尽管使用 Postman,但缺少值
- dbeaver - 如何让 DBeaver 显示保存按钮?
- android - 如何在 nativescript 中启动 android 插件应用程序