使用 ruamel.yaml 修改 YAML 会添加额外的新行

2024-01-11

我需要向 YAML 文件中的现有键添加额外的值。以下是我正在使用的代码。

with open(yaml_in_path, 'r') as f:
    doc, ind, bsi = load_yaml_guess_indent(f, preserve_quotes=True)
doc['phase1'] += ['c']
with open(yaml_out_path, 'w') as f:
    ruamel.yaml.round_trip_dump(doc, f,
                                indent=2, block_seq_indent=bsi)

这就是输入和输出。

Input

phase1:
  - a
  # a comment.
  - b

phase2:
  - d

Output

phase1:
  - a
  # a comment.
  - b

  - c
phase2:
  - d

我怎样才能摆脱之间的新线b and c? (当phase1是文件中唯一的键或者当之间没有空行时phase1 and phase2.)


这里的问题是空行被认为是一种注释,并且注释在ruamel.yaml通过将它们与序列中的元素或映射中的键相关联来保留。该值存储在名为的复杂属性中ca,在列表中类似对象doc['phase1'],与第二个元素相关联。

您当然可以认为它应该与顶级映射/字典相关联,或者与键相关联phase1(作为最后的空行注释)或与phase2作为一些介绍性的空行评论。 上述三者中的任何一个都是有效的,并且当前库中无法控制空行(或注释所在)的策略。

如果您输入“真实”评论(以#) it will可以与相关联的phase1最后,对于那些人来说,策略是不同的。

这显然需要彻底改革,因为最初的目标ruamel.yaml曾是: - 从 YAML 加载一些配置 - 改变一些值 - 将配置保存到 YAML 在这种情况下,不会出现此类追加/插入问题。

因此,在对库进行扩展并控制附加(尾随)注释和/或空行的位置之前,没有真正的解决方案。

在实施此类控制之前,您可以做的最好的事情可能是以下:

import sys
import ruamel.yaml

yaml_str = """\
phase1:
  - a
  # a comment.
  - b

phase2:
  - d
"""

def append_move_comment(l, e):
    i = len(l) - 1
    l.append(e)
    x = l.ca.items[i][0]  # the end comment
    if x is None:
        return
    l.ca.items[i][0] = None
    l.ca.items[i+1] = [x, None, None, None]

data = ruamel.yaml.round_trip_load(yaml_str)
append_move_comment(data['phase1'], 'c')
ruamel.yaml.round_trip_dump(data, sys.stdout, indent=4, block_seq_indent=2)

我改变了indent值为 4,这是您的输入所具有的值(并且因为您将其指定为较小的 block_seq_indent 而获得)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 ruamel.yaml 修改 YAML 会添加额外的新行 的相关文章

随机推荐