1

我想将字典写入 YAML 文件,这就是我现在正在做的事情

from ruamel.yaml import YAML

Flavor_Details = {'Flavor_Details':{
                  'type': 'OS::Nova::Flavor', 
                  'properties': {
                                 'name': 'test-flavor', 
                                 'extra_specs': {"hw:cpu_policy": 'shared'}, 
                                 'ram': 4096, 
                                 'vcpus': 4, 
                                 'disk': 8
                                }
                 }}

output_section = {
                    'server_public_ip':{
                        'description': 'Floating IP address of server',
                        'value': { 'get_attr': [ 'server_floating_ip', 'ip' ] }
                    }
                }

resources_dict = {}
resources_dict.update(Flavor_Details)
resources_dict.update(output_section)

yaml = YAML(typ= 'safe')

with open('test.yaml', 'w') as outfile:
     yaml.dump(resources_dict,outfile)

这是 YAML 文件中的结果

Flavor_Details:
    properties:
      disk: 8
      extra_specs: {hw:cpu_policy: shared}
      name: test-flavor
      ram: 4096
      vcpus: 4
    type: OS::Nova::Flavor
server_public_ip:
    description: Floating IP address of server
    value:
      get_attr: [server__floating_ip, ip]

但我想要这样的结果:

Flavor_Details:
    properties:
      disk: 8
      extra_specs: {"hw:cpu_policy": shared}
      name: test-flavor
      ram: 4096
      vcpus: 4
    type: OS::Nova::Flavor
server_public_ip:
    description: Floating IP address of server
    value: {get_attr: [server__floating_ip, ip]}

我想要"hw:cpu_policy"作为一个字符串,因为在和之间:我想成为这样。hwcpu_policyvalue{get_attr: [server__floating_ip, ip]}

有没有办法得到这样的东西?

4

2 回答 2

2

你可以得到你想要的,但不能使用安全的倾倒器。底层的基于 C 的代码不允许你想要的细粒度控制。

您需要使用默认(往返)转储程序,它允许这种详细控制,因为它需要它来尝试并保留往返行程的布局。

我希望您意识到根据 YAML 规范,YAML 文件中的引号hw:cpu_policy不是必需的,但是 YAML 解析器的一些不正确的实现存在问题。

import sys
import ruamel.yaml

def Q(s):
    return ruamel.yaml.scalarstring.DoubleQuotedScalarString(s)

def F(*args, **kw):
    x = ruamel.yaml.comments.CommentedMap()
    x.fa.set_flow_style()
    for a in args:
        x.update(a)
    x.update(kw)
    return x


Flavor_Details = {'Flavor_Details':{
                  'type': 'OS::Nova::Flavor', 
                  'properties': {
                                 'name': 'test-flavor', 
                                 'extra_specs': F({Q("hw:cpu_policy"): 'shared'}), 
                                 'ram': 4096, 
                                 'vcpus': 4, 
                                 'disk': 8
                                }
                 }}

output_section = {
                    'server_public_ip':{
                        'description': 'Floating IP address of server',
                        'value': F(get_attr=['server_floating_ip', 'ip'])
                    }
                }

resources_dict = {}
resources_dict.update(Flavor_Details)
resources_dict.update(output_section)

yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
yaml.dump(resources_dict, sys.stdout)

这使:

Flavor_Details:
  type: OS::Nova::Flavor
  properties:
    name: test-flavor
    extra_specs: {"hw:cpu_policy": shared}
    ram: 4096
    vcpus: 4
    disk: 8
server_public_ip:
  description: Floating IP address of server
  value: {get_attr: [server_floating_ip, ip]}
于 2020-07-02T08:32:02.250 回答
0

另一种方法是回到 PyYAML 并在输出字符串上使用简单的替换规则。还要注意 和 的重新引用条目。extra_specsvalue

import yaml as yl

Flavor_Details = {'Flavor_Details': {
                  'type': 'OS::Nova::Flavor',
                  'properties': {
                      'name': 'cloudpeak-test-flavor',
                      'extra_specs': "{'hw:cpu_policy': shared}",
                      'ram': 4096,
                      'vcpus': 4,
                      'disk': 8
                  }
                  }}

output_section = {
    'server_public_ip': {
        'description': 'Floating IP address of server',
        'value': '{get_attr: [server_floating_ip, ip]}'
    }
}

resources_dict = {}
resources_dict.update(Flavor_Details)
resources_dict.update(output_section)

out_str = yl.safe_dump(resources_dict)
out_str = out_str.replace("''", '"')
out_str = out_str.replace("'", '')

print(out_str)

with open('test-yl.yaml', 'w') as outfile:
    outfile.write(out_str)

这使:

Flavor_Details:
  properties:
    disk: 8
    extra_specs: {"hw:cpu_policy": shared}
    name: cloudpeak-test-flavor
    ram: 4096
    vcpus: 4
  type: OS::Nova::Flavor
server_public_ip:
  description: Floating IP address of server
  value: {get_attr: [server_floating_ip, ip]}
于 2020-07-02T11:25:59.803 回答