我试图使用ruamel.yaml操作一些YAML文件,特别是删除特定的键。这似乎是可行的,但是在这个过程中,所有在键后面的注释行和空行,直到下一个键,也会被删除。最起码的例子:
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)这意味着:
# Our app configuration
# foo is our main variable
foo: bar
# foz is also important
opt1: foqz有没有一种方法可以避免这种情况,只删除键本身,以及任何内联注释?
发布于 2022-06-23 16:09:49
ruamel.yaml 文档状态
这种保存通常不会中断,除非您严重更改组件的结构(删除dict中的键,删除列表条目)。
因此,这种行为不应该让人感到意外。
您可以做的是将您要删除的键之前的键上的注释与要删除的键上的注释进行扩展(实际上之后可以这样做,因为注释仍在,因此在转储时不再有一个键与其关联)。
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)这意味着:
# 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版本固定在一起。这个内部结构会改变的。
https://stackoverflow.com/questions/72732098
复制相似问题