【问题标题】:How can I insert linebreak in YAML with ruamel.yaml?如何使用 ruamel.yaml 在 YAML 中插入换行符?
【发布时间】:2021-11-21 09:26:57
【问题描述】:

这是我的代码

from ruamel.yaml import YAML

yaml = YAML()
user = [{"login":"login1","fullName":"First1 Last1", "list":["a"]},{"login":"login2","fullName":"First2 Last2", "list":["b"]}]
test = {"category":[{"year":2023,"users":user}]}
yaml.indent(mapping=4, sequence=4, offset=2)
yaml.width = 2048


with open(r'test.yml', 'w') as file:
    documents = yaml.dump(test, file)

我得到了这个 YAML 文件

category:
  - year: 2023
    users:
      - login: login1
        fullName: First1 Last1
        list:
          - a
      - login: login2
        fullName: First2 Last2
        list:
          - b

我需要在两个用户之间插入一个换行符(最终的 YAML 应该是这样的)

category:
  - year: 2023
    users:
      - login: login1
        fullName: First1 Last1
        list:
          - a

      - login: login2
        fullName: First2 Last2
        list:
          - b

如何添加这个空行?

【问题讨论】:

  • 除了对输出文件进行后处理和添加行之外,不确定是否有“正确”的方法。真正的问题是为什么你首先需要额外的行?也许有更好的解决方案?
  • 我需要生成一个与之前已经存在的文件一致的文件,这就是为什么我不能没有这个空行
  • 由于ruamel.yaml可以往返保留空行的YAML文档,不需要后处理,你只需要找出在哪里附加评论(空行被认为是评论不是以 #) 开头的)
  • @AlexandreBarbier 尝试使用问题句,答案对你有帮助。在你原来的“有人能帮忙”上,我能给出的唯一合适的答案是“是的”。欢迎来到Stack Overflow

标签: python yaml ruamel.yaml


【解决方案1】:

您应该在ruamel.yaml 中加载您想要的结果。为了更好的衡量,你可以 然后将其转储回去以查看是否保留了多余的行。如果不是,你可能不会 能够首先写出这样的格式。正如您将看到的那样,额外的行是 保留,所以你应该能够以某种方式在输出中得到它,如果你 可以从头开始重建加载的数据。

ruamel.yaml 通常会将 cmets 附加到刚刚解析的节点上,所以 您应该调查作为第一个键“列表”的值的序列:

import sys
import ruamel.yaml

yaml_str = """\
category:
  - year: 2023
    users:
      - login: login1
        fullName: First1 Last1
        list:
          - a

      - login: login2
        fullName: First2 Last2
        list:
          - b
"""

yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
# yaml.preserve_quotes = True
data = yaml.load(yaml_str)
# yaml.dump(data, sys.stdout)
seq = data['category'][0]['users'][0]['list']
print('seq', type(seq), seq.ca)

给出:

seq <class 'ruamel.yaml.comments.CommentedSeq'> Comment(comment=None,
  items={0: [CommentToken('\n\n', line: 6, col: 12), None, None, None]})

seq.ca 是注释属性。这样的属性不能 添加到普通列表中,因此至少对于您的数据结构的那部分user 您需要创建一个 CommentedSeq 实例。还可以看到评论 令牌由两个换行符 (\n\n) 组成。第一个换行符表示行尾 'a' 后面的注释第一个元素(由0 表示)为空,第二个 换行符是您在第二个“用户”之前的实际空行。

然而,在第二个用户之前插入该行实际上更容易。 CommentedSeq 实例有 一种允许您在键之前添加注释的方法(在这种情况下,键是元素索引):

import sys
import ruamel.yaml
CS = ruamel.yaml.comments.CommentedSeq

yaml = ruamel.yaml.YAML()

user = CS([{"login":"login1","fullName":"First1 Last1", "list":["a"]},{"login":"login2","fullName":"First2 Last2", "list":["b"]}])
user.yaml_set_comment_before_after_key(1, before='\n')
test = {"category":[{"year":2023,"users":user}]}
yaml.indent(mapping=4, sequence=4, offset=2)
yaml.width = 2048


documents = yaml.dump(test, sys.stdout)

给出:

category:
  - year: 2023
    users:
      - login: login1
        fullName: First1 Last1
        list:
          - a

      - login: login2
        fullName: First2 Last2
        list:
          - b

确保您修复了您在安装中使用的 ruamel.yaml 版本, 像yaml_set_comment_before_after_key 这样的例程可能仍然会改变。

在测试期间我通常会写入标准输出,更容易查看输出是否正确。 如果将 YAML 文档写入文件,则应考虑使用扩展名 .yaml,至少 15 年来一直是此类文件的推荐扩展名。

【讨论】:

    猜你喜欢
    • 2017-04-03
    • 2017-07-03
    • 2021-08-30
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 2014-01-06
    • 1970-01-01
    相关资源
    最近更新 更多