python ordereddict还是OrderedDict?

时间:2016-02-02 22:21:07

标签: python pyyaml

我现在很困惑。我正在使用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。 我该如何解决这个问题?

2 个答案:

答案 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)

因为对于往返(您正在使用RoundTripLoaderruamel.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'> 的作者(并且知道它需要更多文档)。