首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ruamel.yaml中保留评论

在ruamel.yaml中保留评论
EN

Stack Overflow用户
提问于 2022-06-23 14:42:06
回答 1查看 246关注 0票数 1

我试图使用ruamel.yaml操作一些YAML文件,特别是删除特定的键。这似乎是可行的,但是在这个过程中,所有在键后面的注释行和空行,直到下一个键,也会被删除。最起码的例子:

代码语言:javascript
复制
from ruamel.yaml import YAML
import sys


yaml_str = """\
# Our app configuration

# foo is our main variable
foo: bar

# foz is also important
foz: quz

# And finally we have our optional configs.
# These are not really mandatory, they can be
# considere as "would be nice".
opt1: foqz
"""


yaml = YAML(typ='rt')
data = yaml.load(yaml_str)

data.pop('foz', None)

yaml.dump(data, sys.stdout)

这意味着:

代码语言:javascript
复制
# Our app configuration

# foo is our main variable
foo: bar

# foz is also important
opt1: foqz

有没有一种方法可以避免这种情况,只删除键本身,以及任何内联注释?

EN

回答 1

Stack Overflow用户

发布于 2022-06-23 16:09:49

ruamel.yaml 文档状态

这种保存通常不会中断,除非您严重更改组件的结构(删除dict中的键,删除列表条目)。

因此,这种行为不应该让人感到意外。

您可以做的是将您要删除的键之前的键上的注释与要删除的键上的注释进行扩展(实际上之后可以这样做,因为注释仍在,因此在转储时不再有一个键与其关联)。

代码语言:javascript
复制
import sys
import ruamel.yaml

yaml_str = """\
# Our app configuration

# foo is our main variable
foo: bar

# foz is also important
foz: quz

# And finally we have our optional configs.
# These are not really mandatory, they can be
# considere as "would be nice".
opt1: foqz
"""

undefined = object()

def my_pop(self, key, default=undefined):
    if key not in self:
        if default is undefined:
            raise KeyError(key)
        return default
    keys = list(self.keys())
    idx = keys.index(key)
    if key in self.ca.items:
        if idx == 0:
            raise NotImplementedError('cannot handle moving comment when popping the first key', key)
        prev = keys[idx-1]
        # print('prev', prev, self.ca)
        comment = self.ca.items.pop(key)[2]
        if prev in self.ca.items:
            self.ca.items[prev][2].value += comment.value
        else:
            self.ca.items[prev] = self.ca.items.pop(key)
    res = self.__getitem__(key)
    self.__delitem__(key)
    return res

ruamel.yaml.comments.CommentedMap.pop = my_pop
    
yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)

data.pop('foz', None)

yaml.dump(data, sys.stdout)

这意味着:

代码语言:javascript
复制
# Our app configuration

# foo is our main variable
foo: bar

# foz is also important


# And finally we have our optional configs.
# These are not really mandatory, they can be
# considere as "would be nice".
opt1: foqz

如果您需要能够弹出注释映射中的第一个键,那么您需要检查self.ca并处理它的comment属性,这有点复杂。

与往常一样,在使用这类内部组件时,您应该将所使用的ruamel.yaml版本固定在一起。这个内部结构会改变的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72732098

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档