为没有通过RoundTripLoader加载*的数据结构生成注释?

时间:2017-01-23 06:45:04

标签: python ruamel.yaml

我有一个数据结构,我想添加注释,然后转换为YAML。

我希望避免将数据结构输出为YAML并使用RoundTripLoader将其重新加载。

有没有办法将我的数据结构转换为支持ruamel.yaml注释界面的数据结构?

1 个答案:

答案 0 :(得分:1)

有一种方法,虽然它的界面不能保证稳定。 由于这一点,以及缺乏文档,通常有助于查看round_trip_loading()您的预期输出或其小样本的表示。

您必须意识到注释附加在结构化节点(映射和序列)的表示的特殊版本上。对于safe_load()作为Python dict的映射,这是一个CommentedMap(),对于一个序列,它将作为Python list加载,这是一个{{1 }}

这两个类都可以有一个CommentedSeq()属性,用于保存结构节点之前可能出现的注释,作为键/值对之后的行尾注释。 item,在键值对或项目之间的自己的行上,以及在节点的末尾。

这意味着您必须转换任何需要注释的.cadict(可以通过例程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)

文件test_comment_manipulation.py有更多示例,是一个值得关注的好地方(随着界面的变化,该文件中的测试也会发生变化)。