如何在保留注释/样式的同时映射到CommentedMap?

2024-04-20 06:42:18 发布

您现在位置:Python中文网/ 问答频道 /正文

给予鲁阿迈尔.亚马尔CommentedMap和一些转换函数f: CommentedMap → Any,我想用转换的键和值生成一个新的CommentedMap,但在其他方面尽可能与原始的类似。你知道吗

如果我不在乎保留风格,我可以这样做:

result = {
    f(key) : f(value)
    for key, value in my_commented_map.items()
}

如果我不需要变换关键点(我也不在乎改变原来的),我可以这样做:

for key, value in my_commented_map.items():
    my_commented_map[key] = f(value)

Tags: key函数inmapforvalue风格my
1条回答
网友
1楼 · 发布于 2024-04-20 06:42:18

样式和注释信息分别附加到 CommentedMap通过特殊属性。你可以复制的样式,但是 注释部分索引到它们出现在哪一行的键,并且 如果你变换那个键,你也需要变换那个键 评论。你知道吗

在第一个示例中,您将f()应用于键和值,我将使用 在我的例子中,函数是分开的,所有的键都是翻转的,还有 所有小写的值(当然这只适用于字符串类型) 键和值,所以这是示例的限制,不是 (解决方案)

import sys
import ruamel.yaml
from ruamel.yaml.comments import CommentedMap as CM
from ruamel.yaml.comments import Format, Comment


yaml_str = """\
# example YAML document
abc: All Strings are Equal  # but some Strings are more Equal then others
klm: Flying Blue
xYz: the End                # for now
"""

def fkey(s):
    return s.upper()

def fval(s):
    return s.lower()

def transform(data, fk, fv):
    d = CM()
    if hasattr(data, Format.attrib):
        setattr(d, Format.attrib, getattr(data, Format.attrib))
    ca = None
    if hasattr(data, Comment.attrib):
        setattr(d, Comment.attrib, getattr(data, Comment.attrib))
        ca = getattr(d, Comment.attrib)
    # as the key mapping could map new keys on old keys, first gather everything
    key_com = {}
    for k in data:
        new_k = fk(k)
        d[new_k] = fv(data[k])
        if ca is not None and k in ca.items:
            key_com[new_k] = ca.items.pop(k)
    if ca is not None:
        assert len(ca.items) == 0
        ca._items = key_com  # the attribute, not the read-only property
    return d

yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)

# the following will print any new CommentedMap with curly braces, this just here to check
# if the style attribute copying is working correctly, remove from real code
yaml.default_flow_style = True

data = transform(data, fkey, fval)
yaml.dump(data, sys.stdout)

它给出:

# example YAML document
ABC: all strings are equal  # but some Strings are more Equal then others
KLM: flying blue
XYZ: the end                # for now

请注意:

  • 上面的方法尝试(并成功)在原文中开始注释 列,例如当转换的键或 值占用更多空间,它被进一步向右推。

  • 如果您有一个更复杂的数据结构,递归地遍历树,向下进入映射 和序列。在这种情况下,存储(key, value, comment)元组可能更容易 然后pop()所有键并重新插入存储的值(而不是重建树)。

相关问题 更多 >