繁体   English   中英

pythonordereddict或OrderedDict?

[英]python ordereddict or OrderedDict?

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

您几乎可以肯定没有使用pyyaml ,因为它没有RoundTripLoader 相反,您可能正在使用ruamel.yaml

此替代方法在python 2安装上使用其自己的ruamel.ordereddict在python 3上使用本机collections.OrderedDict 。该替代方法支持OrderedDict进行的大多数操作,因此没有理由您无法对其进行操作。 请参阅其文档。

但是,如果您希望从一种转换为另一种,则可以执行以下操作:

x = collections.OrderedDict(some_ruamel_ordered_dict.items())

发生了一些奇怪的事情,或者您没有使用代码示例来加载该文件,然后从data获取打印内容。 如果您确实在使用yaml.load_all ,它将为您提供一个生成器对象,该对象使您可以遍历该文件中的1个或多个YAML文档。 由于您没有使用文档指令标记 ,因此使用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))

给定:dev上面示例中的实际数据类型是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)

因为进行ruamel.yaml (您正在使用RoundTripLoader ), ruamel.yaml需要保留订单,并有一个地方可以保留任何注释和其他信息,这在使用dict时是不可能的。 ordereddict只是围绕ruamel.ordereddict (如果有)或OrderedDict的便利类。

当然,您可以像上面一样导入ordereddict并使用它,但是如果您不需要字典中的往返或顺序保留(即dict很好),则只需使用标准加载程序即可:

data = yaml.load(open('testingyaml.yaml'))
print(type(data))

印刷品:

<type 'dict'>

我建议不要使用PyYAML进行“降级”:它仅实现旧版本的YAML 1.1,尽管ruamel.yaml是PyYAML的派生产品,但由于它是派生的,因此它解决了许多最初需要解决的问题,仍然属于PyYAML²。


¹ruamel.ordereddict是Order dict的(快速)C实现,在OrderedDict出现在标准库中之前已经存在了几年,因为标准库版本具有少量的功能子集,直到Python 3.5变得(缓慢) Python,切换到OrderedDict对我来说从来不是真正的选择。
² 但是后来我还是有偏见的,因为我是ruamel.yaml的作者(并且知道它需要更多的文档)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM