格式化PyYAML dump()输出

nop*_*ope 18 python yaml pyyaml

我有一个字典列表,我想序列化:

list_of_dicts = [ { 'key_1': 'value_a', 'key_2': 'value_b'},
                  { 'key_1': 'value_c', 'key_2': 'value_d'},
                  ...
                  { 'key_1': 'value_x', 'key_2': 'value_y'}  ]

yaml.dump(list_of_dicts, file, default_flow_style = False)
Run Code Online (Sandbox Code Playgroud)

产生以下内容:

- key_1: value_a
  key_2: value_b
- key_1: value_c
  key_2: value_d
(...)
- key_1: value_x
  key_2: value_y
Run Code Online (Sandbox Code Playgroud)

但我想得到这个:

- key_1: value_a
  key_2: value_b
                     <-|
- key_1: value_c       | 
  key_2: value_d       |  empty lines between blocks
(...)                  |
                     <-|
- key_1: value_x
  key_2: value_y
Run Code Online (Sandbox Code Playgroud)

PyYAML 文档dump()非常简短地讨论了参数,似乎没有关于这个特定主题的任何内容.

手动编辑文件以添加换行符可以提高可读性,之后结构仍然很好,但我不知道如何使dump方法生成它.

一般来说,除了简单的缩进之外,还有一种方法可以更好地控制输出格式吗?

Yur*_*rov 16

使用库没有简单的方法(yaml转储器语法树中的Node对象是被动的,无法发出此信息),所以我最终得到了

stream = yaml.dump(list_of_dicts, default_flow_style = False)
file.write(stream.replace('\n- ', '\n\n- '))
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!不得不使用类似的东西来格式化列表。PyYAML 不会在 `-` 之前放置缩进,而 YAML 消耗库,我们在那里使用预期的一些缩进。所以我们必须做`replace('- ', ' - ')` (3认同)

Ant*_*hon 5

PyYAML 文档只dump()简要讨论了参数,因为没有太多可说的。PyYAML 不提供这种控制。

为了允许在加载的 YAML 中保留此类空(和注释)行,我开始开发该ruamel.yaml库,这是停滞的 PyYAML 的超集,具有 YAML 1.2 兼容性,添加了许多功能并修复了错误。有了ruamel.yaml你可以这样做:

import sys
import ruamel.yaml

yaml_str = """\
- key_1: value_a
  key_2: value_b

- key_1: value_c
  key_2: value_d

- key_1: value_x  # a few before this were ellipsed
  key_2: value_y
"""

yaml = ruamel.yaml.YAML()
data = yaml.load(yaml_str)
yaml.dump(data, sys.stdout)
Run Code Online (Sandbox Code Playgroud)

并获得与输入字符串完全相同的输出(包括注释)。

您还可以从头开始构建您想要的输出:

import sys
import ruamel.yaml

yaml = ruamel.yaml.YAML()
list_of_dicts = yaml.seq([ { 'key_1': 'value_a', 'key_2': 'value_b'},
                           { 'key_1': 'value_c', 'key_2': 'value_d'},
                           { 'key_1': 'value_x', 'key_2': 'value_y'}  ])

for idx in range(1, len(list_of_dicts)):
    list_of_dicts.yaml_set_comment_before_after_key(idx, before='\n')

ruamel.yaml.comments.dump_comments(list_of_dicts)
yaml.dump(list_of_dicts, sys.stdout)
Run Code Online (Sandbox Code Playgroud)

yaml.seq()需要使用转换来创建允许通过特殊属性附加空行的对象。

该库还允许保存/轻松设置字符串上的引号和文字样式、int 格式(十六进制、八进制、二进制)和浮点数。以及映射和序列的单独缩进规范(尽管不是单个映射或序列)。

  • 很好的答案,并为 fork 自己改进的 yaml 解析器干杯,我现在会尝试一下,因为我现在正在自己研究转储格式问题。但我发现,自从这篇文章发布以来,pyyaml 一直在持续更新。从那以后他们在格式方面有改进吗?或者您的任何贡献是否已合并到 pyyaml 中? (2认同)