我有一个数据结构,我想添加注释,然后转换为 YAML。
我想避免将数据结构输出为 YAML 并使用RoundTripLoader
.
有没有办法将我的数据结构转换为支持 ruamel.yaml 注释接口的数据结构?
我有一个数据结构,我想添加注释,然后转换为 YAML。
我想避免将数据结构输出为 YAML 并使用RoundTripLoader
.
有没有办法将我的数据结构转换为支持 ruamel.yaml 注释接口的数据结构?
有一种方法,尽管不能保证该接口是稳定的。正因为如此,并且缺乏文档,因此查看round_trip_loading()
预期输出的表示或其中的小样本通常会有所帮助。
您必须意识到注释附加到结构化节点(映射和序列)的表示的特殊版本。对于将safe_load()
作为 Python的映射dict
,这是 a CommentedMap()
,对于将作为 Python 加载的序列,list
这是 a CommentedSeq()
。
这两个类都可以有一个.ca
属性来保存可能出现在结构节点之前的注释,作为键/值对之后的行尾注释。项目,在键值对或项目之间的自己的行上,在节点的末尾。
这意味着您必须转换任何dict
需要list
评论的内容(可以自动/递归地完成,例如通过例程comment_prep()
),然后找到正确的点和方式来附加评论。因为评论操作例程还没有稳定下来,所以确保你包装你的评论添加例程,以便获得一个可以更新的地方,以防它们发生变化。
import sys
from ruamel.yaml import round_trip_dump as rtd
from ruamel.yaml.comments import CommentedMap, CommentedSeq
# please note that because of the dict the order of the keys is undetermined
data = dict(a=1, b=2, c=['x', 'y', dict(k='i', l=42, m='∞')])
rtd(data, sys.stdout)
print('-' * 30)
def comment_prep(base):
"""replace all dict with CommentedMap and list with CommentedSeq"""
if isinstance(base, dict):
ret_val = CommentedMap()
for key in sorted(base): # here we force sorted order
ret_val[key] = comment_prep(base[key])
return ret_val
if isinstance(base, list):
ret_val = CommentedSeq()
for item in base:
ret_val.append(comment_prep(item))
return ret_val
return base
data = comment_prep(data)
data['c'][2].yaml_add_eol_comment('# this is the answer', key='l', column=15)
rtd(data, sys.stdout)
给出:
c:
- x
- y
- k: i
m: ∞
l: 42
b: 2
a: 1
------------------------------
a: 1
b: 2
c:
- x
- y
- k: i
l: 42 # this is the answer
m: ∞
文件test_comment_manipulation.py有更多示例,是一个值得关注的好地方(随着界面的变化,该文件中的测试也会发生变化)。