PyYAML,safe_dump在YAML文件中添加换行符和缩进

时间:2016-05-10 13:10:20

标签: python-2.7 pyyaml

我想收到以下YAML文件:

---
classes:
  - apache
  - ntp

apache::first: 1
apache::package_ensure: present
apache::port: 999
apache::second: 2
apache::service_ensure: running

ntp::bla: bla
ntp::package_ensure: present
ntp::servers: '-'

解析后,我收到了这样的输出:

---
apache::first: 1
apache::package_ensure: present
apache::port: 999
apache::second: 2
apache::service_ensure: running
classes:
- apache
- ntp
ntp::bla: bla
ntp::package_ensure: present
ntp::servers: '-'

Here,我找到了可以设置样式文档的属性。我试图设置line_break和缩进,但它不起作用。

 with open(config['REPOSITORY_PATH'] + '/' + file_name, 'w+') as file:
            yaml.safe_dump(data_map, file, indent=10, explicit_start=True, explicit_end=True, default_flow_style=False,
                           line_break=1)
        file.close()

请告诉我简单的输出样式。

1 个答案:

答案 0 :(得分:3)

你不能在PyYAML那样做。 indent选项仅影响映射而不影响序列。 PyYAML也不会在往返时保留映射键的顺序。

如果您使用ruamel.yaml(免责声明:我是该软件包的作者),那么获得与输出完全相同的输入很容易:

import ruamel.yaml

yaml_str = """\
---
classes:
  - apache   # keep the indentation
  - ntp

apache::first: 1
apache::package_ensure: present
apache::port: 999
apache::second: 2
apache::service_ensure: running

ntp::bla: bla
ntp::package_ensure: present
ntp::servers: '-'
"""

data = ruamel.yaml.round_trip_load(yaml_str)
res = ruamel.yaml.round_trip_dump(data, indent=4, block_seq_indent=2,
                            explicit_start=True)
assert res == yaml_str

请注意,它还保留了我添加到第一个序列元素的注释。

您可以从“临时”构建此内容,但添加换行符不是ruamel.yaml中存在调用的内容:

import ruamel.yaml
from ruamel.yaml.tokens import CommentToken
from ruamel.yaml.error import Mark
from ruamel.yaml.comments import CommentedMap, CommentedSeq


data = CommentedMap()
data['classes'] = classes = CommentedSeq()
classes.append('apache')
classes.append('ntp')

data['apache::first'] = 1
data['apache::package_ensure'] = 'present'
data['apache::port'] = 999
data['apache::second'] = 2
data['apache::service_ensure'] = 'running'
data['ntp::bla'] = 'bla'
data['ntp::package_ensure'] = 'present'
data['ntp::servers'] = '-'


m = Mark(None, None, None, 0, None, None)
data['classes'].ca.items[1] = [CommentToken('\n\n', m, None), None, None, None]
#                        ^ 1 is the last item in the list
data.ca.items['apache::service_ensure'] = [None, None, CommentToken('\n\n', m, None), None]

res = ruamel.yaml.round_trip_dump(data, indent=4, block_seq_indent=2,
                            explicit_start=True)
print(res, end='')

您必须将换行添加为注释(不带“#”)到换行符之前的最后一个元素,即最后一个列表元素和apache::service_ensure映射条目。

除此之外,您应该问自己是否真的想要使用PyYAML,它仅支持2005年的YAML 1.1(大部分),而不是2009年的最新修订YAML 1.2。

您链接到的wordpress页面似乎不太严重(它甚至没有包名称PyYAML,正确)。