我现在很困惑。我正在使用PyYAML编辑一些YAML文件。
data = yaml.load_all(open('testingyaml.yaml'),Loader=yaml.RoundTripLoader)
我的testingyaml.yaml文件包含以下内容:
spring:
profiles: dev
datasource:
url: jdbc:postgresql://127.0.0.1:5432/nfvgrid
dns:
enable: false
cassandra:
host: 192.168.7.151
当我打印数据时,它会打印以下内容:
ordereddict([('spring', ordereddict([('profiles', 'dev'), ('datasource', ordereddict([('url', 'jdbc:postgresql://127.0.0.1:5432/nfvgrid')]))])), ('dns', ordereddict([('enable', False)])), ('cassandra', ordereddict([('host', '192.168.7.151')]))])
我还想在这个有序字典上执行一些操作,但是python会抛出错误NameError: name 'ordereddict' is not defined
它通常是OrderedDict
但不知何故PyYAML返回ordereddict。
我该如何解决这个问题?
答案 0 :(得分:3)
您几乎肯定没有使用pyyaml
,因为它没有RoundTripLoader
。相反,您可能正在使用ruamel.yaml
。
此替代方法在python 2安装上使用自己的ruamel.ordereddict
,在python 3上使用本机collections.OrderedDict
。此替代方案支持OrderedDict执行的大多数操作,因此没有理由不能操作它。请参阅其文档。
但是,如果您希望从一个转换为另一个,您可以执行以下操作:
x = collections.OrderedDict(some_ruamel_ordered_dict.items())
答案 1 :(得分:2)
发生了一些奇怪的事情,或者您没有使用代码示例来加载该文件,然后从data
获取该打印件。如果您真的使用yaml.load_all
将返回一个生成器对象,该对象允许您跳过该文件中的一个或多个YAML文档。由于您未使用document directive markers,因此使用load_all()
:
from __future__ import print_function
import ruamel.yaml as yaml
datas = yaml.load_all(open('testingyaml.yaml'), Loader=yaml.RoundTripLoader)
print(datas, '\n', '-' * 50, sep='')
for data in datas:
print(data['spring']['profiles'])
print(type(data))
给出:
开发
上例中的实际数据类型是ruamel.yaml.comments.CommentedMap
,如果你做得更简单,你也会得到它:
data = yaml.load(open('testingyaml.yaml'), Loader=yaml.RoundTripLoader)
print(type(data))
打印<class 'ruamel.yaml.comments.CommentedMap'>
(不使用load()
代替loadall()
。
CommentedMap
源自ordereddict
from ruamel.yaml.compat import ordereddict
from ruamel.yaml.comments import CommentedMap
assert issubclass(CommentedMap, ordereddict)
因为对于往返(您正在使用RoundTripLoader
)ruamel.yaml
需要保留顺序并且有地方附加任何注释和其他信息以保留,这在使用{{1时不可能}}。 dict
只是ordereddict
(如果有)或ruamel.ordereddict
¹的便利课程。
你当然可以像上面那样自己导入OrderedDict
并使用它,但是如果你不需要在你的词典中进行往返或保存顺序(即ordereddict
都可以),那么只需使用标准装载机:
dict
打印:
data = yaml.load(open('testingyaml.yaml'))
print(type(data))
我建议不要使用PyYAML来“降级”:它只实现了旧的1.1版本的YAML,虽然ruamel.yaml是PyYAML的衍生物,但由于它是派生的,因此它解决了很多问题。提起反对,仍然属于PyYAML²。
¹ ruamel.ordereddict是有序dicts的(快速)C实现,在OrderedDict出现在标准库之前已经存在了几年,因为标准库版本有一小部分功能,直到Python 3.5是(慢)纯Python,切换到OrderedDict对我来说从来都不是一个选项。
²然后我有偏见,因为我是<type 'dict'>
的作者(并且知道它需要更多文档)。