我遇到以下问题:将YAML文件中的文档映射到dict
并正确映射它们。
我有以下YAML文件,它代表服务器(db.yml
):
instanceId: i-aaaaaaaa
environment:us-east
serverId:someServer
awsHostname:ip-someip
serverName:somewebsite.com
ipAddr:192.168.0.1
roles:[webserver,php]
我加载了这个YAML文件,我可以毫无问题地做,我想我明白了。
instanceId = getInstanceId()
stream = file('db.yml', 'r')
dict = yaml.load_all(stream)
for key in dict:
if key in dict == "instanceId":
print key, dict[key]
我希望逻辑能够像以下一样工作:
instanceId
与getInstanceId()
设置的匹配,则打印出该文档的所有键和值。如果我从命令行查看地图数据结构,我会得到:
{'instanceId': 'i-aaaaaaaa environment:us-east serverId:someServer awsHostname:ip-someip serverName:someserver ipAddr:192.168.0.1 roles:[webserver,php]'}
我想我可能不正确地为YAML文件创建数据结构,并且在匹配dict
上的内容时,我有点迷失。
附注:我无法使用yaml.load()
加载此文件中的所有文档,我尝试了yaml.load_all()
,这似乎有用,但我的主要问题仍然存在。
答案 0 :(得分:28)
我认为您的yaml文件应该看起来像(或者至少是类似的,所以无论如何它的结构都是正确的):
instance:
Id: i-aaaaaaaa
environment: us-east
serverId: someServer
awsHostname: ip-someip
serverName: somewebsite.com
ipAddr: 192.168.0.1
roles: [webserver,php]
然后,yaml.load(...)
返回:
{'instance': {'environment': 'us-east', 'roles': ['webserver', 'php'], 'awsHostname': 'ip-someip', 'serverName': 'somewebsite.com', 'ipAddr': '192.168.0.1', 'serverId': 'someServer', 'Id': 'i-aaaaaaaa'}}
你可以从那里去......
如此使用:
>>> for key, value in yaml.load(open('test.txt'))['instance'].iteritems():
print key, value
environment us-east
roles ['webserver', 'php']
awsHostname ip-someip
serverName somewebsite.com
ipAddr 192.168.0.1
serverId someServer
Id i-aaaaaaaa
答案 1 :(得分:3)
您的代码中的其他错误,与YAML无关:
for key in dict:
if key in dict == "instanceId": # This doesn't do what you want
print key, dict[key]
in
是一个适用于sequence types的运算符,也适用于地图。这就是为什么这不是一个语法错误...但它并没有做你想要的。
key in dict
将始终评估为True
,因为您正在迭代的所有密钥都在dict中。因此,您的代码归结为True == "instanceId"
,它总是会计算为False
,因为布尔值True
永远不会等于该字符串。
您可能已经注意到print
语句不会产生任何输出;这是因为它永远不会被召唤。
答案 2 :(得分:1)
仅使用python-benedict
,它是一个dict子类,它为大多数常见格式(包括yaml
)提供I / O支持。
from benedict import benedict
# path can be a yaml string, a filepath or a remote url
path = 'path/to/data.yml'
d = benedict.from_yaml(path)
# do stuff with your dict
# ...
# write it back to disk
d.to_yaml(filepath=path)
它已经过充分测试和记录,请查看自述文件以查看所有功能: https://github.com/fabiocaccamo/python-benedict
使用pip安装:pip install python-benedict
答案 3 :(得分:0)
您可以将bios
软件包用于python3,如下所示。
import bios
my_dict = bios.read('data.yml')
BIOS正在从文件读取原始数据并转换python dict对象。根据文件的扩展名,可以确定文件类型。