Yaml dump python 字典作为不带单引号的映射

Yaml dump python dictionary as mapping without single quotes

我想将一个 dict 转储到一个没有引号的 yaml 文件中。基本上就像一个映射

import yaml

windows_list = []
server_list = ['abc-def-01', 'pqr-str-02']
site_list = ['dev', 'prod']

server_dict = dict(zip(server_list, site_list))

for k,v in server_dict.items():
    a = '{ SERVER: '+k+', SITE: '+v+' }'
    windows_list.append(a)

final_dict = {'service':'something','servers': windows_list}

with open('config.yml', 'w') as yaml_file:
    yaml.dump(final_dict, yaml_file, default_flow_style=False)

config.yml 的输出如下:

service: some name
servers:
- '{ SERVER: abc-def-01, SITE: dev }'
- '{ SERVER: pqr-str-02, SITE: prod }'

我不想要它周围的引号。我希望它是一个没有引号的映射

期望的输出

service: some name
servers:
- { SERVER: abc-def-01, SITE: dev }
- { SERVER: pqr-str-02, SITE: prod }

我读了 ,它说如果您有特殊字符,则无法删除引号,但我想知道是否有某种解决方法可以实现我想要的。

试试这个:

for k,v in server_dict.items():
    a = { 'SERVER': f'{k}', 'SITE': f'{v}' }
    windows_list.append(a)

final_dict = {'service':'something','servers': windows_list}

with open('config.yml', 'w') as yaml_file:
    yaml.dump(final_dict, yaml_file, default_flow_style=False)

它将在 yaml 中生成您所需要的内容 format/structure:

servers:
- SERVER: abc-def-01
  SITE: dev
- SERVER: pqr-str-02
  SITE: prod
service: something

HTH

如果你想输出一个字典,不要构造一个字符串。构造一个字典:

import yaml

windows_list = []
server_list = ['abc-def-01', 'pqr-str-02']
site_list = ['dev', 'prod']

server_dict = dict(zip(server_list, site_list))

for k,v in server_dict.items():
    windows_list.append({'SERVER': k, 'SITE': v})

final_dict = {'service':'something','servers': windows_list}

with open('config.yml', 'w') as yaml_file:
    yaml.dump(final_dict, yaml_file, default_flow_style=False)

这将输出

servers:
- SERVER: abc-def-01
  SITE: dev
- SERVER: pqr-str-02
  SITE: prod
service: something

如果您希望项目以流式表示,您可以使用自定义表示器:

import yaml

windows_list = []
server_list = ['abc-def-01', 'pqr-str-02']
site_list = ['dev', 'prod']

class ServerMap:
    def __init__(self, server, site):
        self.server = server
        self.site = site

def servermap_representer(dumper, data):
    return dumper.represent_mapping('tag:yaml.org,2002:map',
            {'SERVER': data.server, 'SITE': data.site}, [True, True])

yaml.add_representer(ServerMap, servermap_representer)

server_dict = dict(zip(server_list, site_list))

for k,v in server_dict.items():
    windows_list.append(ServerMap(k, v))

final_dict = {'service':'something','servers': windows_list}

with open('config.yml', 'w') as yaml_file:
    yaml.dump(final_dict, yaml_file, default_flow_style=False)

输出:

servers:
- {SERVER: abc-def-01, SITE: dev}
- {SERVER: pqr-str-02, SITE: prod}
service: something

引号是必需的,因为您创建和转储的字符串看起来像流式 映射。换句话说,当你加载你想要的东西时,你会得到一个不同的 数据结构比你“手工”创建的(或者从你得到的输出加载)。

如果您遇到这种情况,最好的办法是加载您想要的内容,然后 转储 Python 数据结构,以便您知道需要创建什么。这也验证了你想要的是否真的是 YAML:

import sys
import ruamel.yaml

yaml_str = """\
service: some name
servers:
- { SERVER: abc-def-01, SITE: dev }
- { SERVER: pqr-str-02, SITE: prod }
"""

yaml = ruamel.yaml.YAML(typ='safe')
data = yaml.load(yaml_str)
print(data)

给出:

{'service': 'some name', 'servers': [{'SERVER': 'abc-def-01', 'SITE': 'dev'}, {'SERVER': 'pqr-str-02', 'SITE': 'prod'}]}

如您所见,序列由字典组成,因此您需要追加:

import sys
import ruamel.yaml


windows_list = []
server_list = ['abc-def-01', 'pqr-str-02']
site_list = ['dev', 'prod']

server_dict = dict(zip(server_list, site_list))

for k,v in server_dict.items():
    a = { 'SERVER': k, 'SITE': v }
    windows_list.append(a)

final_dict = {'service':'something', 'servers': windows_list}

yaml = ruamel.yaml.YAML()
yaml.default_flow_style = None
yaml.dump(final_dict, sys.stdout)

这导致:

service: something
servers:
- {SERVER: abc-def-01, SITE: dev}
- {SERVER: pqr-str-02, SITE: prod}

顺便说一句。自 2006 年 9 月以来,YAML 文件的推荐扩展名是 .yaml