用pyyaml输出不正确

时间:2017-11-21 16:52:16

标签: python pyyaml ruamel.yaml

我有一个YAML文件,test.yaml

test:
  server_group_1:
    type: OS::Nova::ServerGroup
    properties:
      name: { get_param: [server_groups, 5] }
      policies: [ { get_param: [server_group_types, 5] } ]

当我使用PyYAML读取并打印输出时,它会给出低于输出的输出,这与输入不同

test:
  server_group_1:
    properties:
      name:
        get_param:
        - server_groups
        - 5
      policies:
      - get_param:
        - server_group_types
        - 5
    type: OS::Nova::ServerGroup

代码:

import yaml
print yaml.dump(yaml.load(open('/test.yaml')), default_flow_style=False)

我希望输出与输入相同,此处的顺序也会发生变化

1 个答案:

答案 0 :(得分:0)

你的简短PyYAML代码有几个问题,与映射中的键顺序无关(PyYAML总是排序)。

几乎不需要使用没有load()参数的PyYAML Loader,这被证明是不安全的。并且您无法向dump()提供流参数,这会导致将输出写入内存,检索并然后print。如果你想试验PyYAML,你应该使用dump(yaml.safe_load(open('/test.yaml')), sys.stdout, default_flow_style=False)

尽管可以将PyYAML映射作为Python有序字典加载,但这并非易事。

更有问题的是嵌套流式样,例如: {get_param: [server_groups, 5]}其中流样式列表嵌套在流样式映射中。流式样的PyYAML控件是以下三种之一:根本没有流式,或者所有流式,或者所有叶节点流式。

你应该看看ruamel.yaml(免责声明:我是该套餐的作者)你可以做的事情:

import sys
import ruamel.yaml

yaml = ruamel.yaml.YAML()

with open('test.yaml') as fp:
    data = yaml.load(fp)
yaml.dump(data, sys.stdout)

这保留了键顺序,并且所有级别都保留了流样式。您无法控制的唯一事情是流式样式花括号之后/之前的额外空格以及流式样方括号之后/之前的不一致空格。

使用上面的代码,你得到:

test:
  server_group_1:
    type: OS::Nova::ServerGroup
    properties:
      name: {get_param: [server_groups, 5]}
      policies: [{get_param: [server_group_types, 5]}]