1

我有一个 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)

我希望输出与输入相同,这里的顺序也发生了变化

4

1 回答 1

1

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

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


尽管可以将 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]}]
于 2017-11-21T20:45:33.340 回答