我有一个字典列表,我想序列化:
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)
产生以下内容:
- key_1: value_a
key_2: value_b
- key_1: value_c
key_2: value_d
(...)
- key_1: value_x
key_2: value_y
但是我想得到这个:
- 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
PyYAML documentation非常简短地谈论dump()
个论点,似乎没有任何关于这个特定主题的内容。
手动编辑文件以添加换行符可以提高可读性,之后结构仍然很好,但我不知道如何使dump方法生成它。
总的来说,除了简单的缩进之外,还有一种方法可以更好地控制输出格式吗?
答案 0 :(得分:15)
使用库没有简单的方法(yaml dumper语法树中的Node对象是被动的,无法发出此信息),所以我最终得到了
stream = yaml.dump(list_of_dicts, default_flow_style = False)
file.write(stream.replace('\n- ', '\n\n- '))
答案 1 :(得分:2)
PyYAML文档仅简要讨论dump()
个参数,因为没有太多可说的。 PyYAML不提供这种控制。
为了保留加载的YAML中的这些空(和注释)行,我开始开发ruamel.yaml
库,停滞的PyYAML的超集,兼容YAML 1.2,添加了许多功能和bug固定。使用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)
并获得与输入字符串完全相同的输出(包括注释)。
您还可以从头开始构建所需的输出:
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)
使用yaml.seq()
进行转换是创建允许通过特殊属性附加空行的对象所必需的。
该库还允许保留/轻松设置字符串上的引号和文字样式,int(十六进制,八进制,二进制)和浮点数的格式。以及映射和序列的单独缩进规范(尽管不是针对单个映射或序列)。
答案 2 :(得分:0)
虽然它有点笨拙,但我的目标与OP相同。 我通过继承yaml.Dumper
解决了这个问题from yaml import Dumper
class MyDumper(Dumper):
def write_indent(self):
indent = self.indent or 0
if not self.indention or self.column > indent \
or (self.column == indent and not self.whitespace):
self.write_line_break()
##########$#######################################
# On the first level of indentation, add an extra
# newline
if indent == 2:
self.write_line_break()
##################################################
if self.column < indent:
self.whitespace = True
data = u' '*(indent-self.column)
self.column = indent
if self.encoding:
data = data.encode(self.encoding)
self.stream.write(data)
您可以这样称呼:
print dump(python_dict, default_flow_style=False, width=79, Dumper=MyDumper)