gpt4 book ai didi

python - 使用 ruamel 保留合并键和显式键的相对顺序

转载 作者:行者123 更新时间:2023-12-01 08:26:31 25 4
gpt4 key购买 nike

我希望使用 ruamel.yaml 对大型人工编辑的 YAML 文件执行一些自动编辑。

输入文件包含合并键,如下所示:

foo: &foo
color: red

bar:
name: qux
<<: *foo

如果可能,我想保留显式 name 的相对顺序。键和 <<合并键,但看起来鲁梅尔确实希望合并键放在第一位。这是我通过 ruamel 往返此 YAML 时得到的结果:

foo: &foo
color: red

bar:
<<: *foo
name: qux

有什么方法可以告诉 ruamel 保留此 block 中合并键的位置吗?

最佳答案

通过调整表示器中的两条线来进行映射可以修复,合并键的位置信息就在那里,它只是没有被使用。不幸的是,这是一个相当大的函数需要一些导入:

import sys
import ruamel.yaml

if ruamel.yaml.version_info < (0, 15, 86):
from ruamel.yaml.nodes import MappingNode, ScalarNode
from ruamel.yaml.comments import comment_attrib, merge_attrib

def represent_mapping(self, tag, mapping, flow_style=None):
value = []
try:
flow_style = mapping.fa.flow_style(flow_style)
except AttributeError:
flow_style = flow_style
try:
anchor = mapping.yaml_anchor()
except AttributeError:
anchor = None
node = MappingNode(tag, value, flow_style=flow_style, anchor=anchor)
if self.alias_key is not None:
self.represented_objects[self.alias_key] = node
best_style = True
# no sorting! !!
try:
comment = getattr(mapping, comment_attrib)
node.comment = comment.comment
if node.comment and node.comment[1]:
for ct in node.comment[1]:
ct.reset()
item_comments = comment.items
for v in item_comments.values():
if v and v[1]:
for ct in v[1]:
ct.reset()
try:
node.comment.append(comment.end)
except AttributeError:
pass
except AttributeError:
item_comments = {}
merge_list = [m[1] for m in getattr(mapping, merge_attrib, [])]
merge_pos = getattr(mapping, merge_attrib, [[0]])[0][0] # <<<<<<<< line added
item_count = 0
if bool(merge_list):
items = mapping.non_merged_items()
else:
items = mapping.items()
for item_key, item_value in items:
item_count += 1
node_key = self.represent_key(item_key)
node_value = self.represent_data(item_value)
item_comment = item_comments.get(item_key)
if item_comment:
assert getattr(node_key, 'comment', None) is None
node_key.comment = item_comment[:2]
nvc = getattr(node_value, 'comment', None)
if nvc is not None: # end comment already there
nvc[0] = item_comment[2]
nvc[1] = item_comment[3]
else:
node_value.comment = item_comment[2:]
if not (isinstance(node_key, ScalarNode) and not node_key.style):
best_style = False
if not (isinstance(node_value, ScalarNode) and not node_value.style):
best_style = False
value.append((node_key, node_value))
if flow_style is None:
if ((item_count != 0) or bool(merge_list)) and self.default_flow_style is not None:
node.flow_style = self.default_flow_style
else:
node.flow_style = best_style
if bool(merge_list):
# because of the call to represent_data here, the anchors
# are marked as being used and thereby created
if len(merge_list) == 1:
arg = self.represent_data(merge_list[0])
else:
arg = self.represent_data(merge_list)
arg.flow_style = True
value.insert(merge_pos, (ScalarNode(u'tag:yaml.org,2002:merge', '<<'), arg)) # <<<<< line changed
return node

ruamel.yaml.representer.RoundTripRepresenter.represent_mapping = represent_mapping



yaml_str = """\
foo: &foo
color: red

bar:
name: qux
<<: *foo
"""

yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)

给出:

foo: &foo
color: red

bar:
name: qux
<<: *foo

上面尝试保持绝对位置,不进行删除或插入键值对。

使用下一版本时,上述内容不会修补任何内容ruamel.yaml,其中将包含这些更改。

关于python - 使用 ruamel 保留合并键和显式键的相对顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54204865/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com