我想让Python的加载器将映射(和有序映射)加载到PyYAML 2.7+ OrderedDict类型中,而不是普通的dict
和它当前使用的对列表中。
那么最好的方法是什么呢?
发布于 2014-01-10 23:26:03
yaml模块允许您指定自定义“表示者”以将Python对象转换为文本,并指定“构造器”以反转该过程。
_mapping_tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG
def dict_representer(dumper, data):
return dumper.represent_dict(data.iteritems())
def dict_constructor(loader, node):
return collections.OrderedDict(loader.construct_pairs(node))
yaml.add_representer(collections.OrderedDict, dict_representer)
yaml.add_constructor(_mapping_tag, dict_constructor)
发布于 2015-06-11 02:02:07
2015 (及更高版本)选项:
ruamel.yaml是PyYAML的一个替代品(免责声明:我是这个包的作者)。保留映射的顺序是在2015年的第一个版本(0.1)中添加的内容之一。它不仅保留了字典的顺序,还保留了注释、主播名称、标签,并支持YAML1.2规范(2009年发布)
规范说不能保证排序,但YAML文件中当然有排序,适当的解析器可以保留它,并透明地生成一个保持排序的对象。您只需选择正确的解析器、加载器和转储程序:
import sys
from ruamel.yaml import YAML
yaml_str = """\
3: abc
conf:
10: def
3: gij # h is missing
more:
- what
- else
"""
yaml = YAML()
data = yaml.load(yaml_str)
data['conf'][10] = 'klm'
data['conf'][3] = 'jig'
yaml.dump(data, sys.stdout)
将为您提供:
3: abc
conf:
10: klm
3: jig # h is missing
more:
- what
- else
data
的类型是CommentedMap
,它的功能类似于字典,但是它有额外的信息,这些信息会一直保留到被转储(包括保留的注释!)
发布于 2013-08-26 05:48:02
在我的Python2.7的PyYaml安装中,我更新了__init__.py、constructor.py和loader.py。现在支持load命令的object_pairs_hook选项。我所做的更改的差异如下所示。
__init__.py
$ diff __init__.py Original
64c64
< def load(stream, Loader=Loader, **kwds):
---
> def load(stream, Loader=Loader):
69c69
< loader = Loader(stream, **kwds)
---
> loader = Loader(stream)
75c75
< def load_all(stream, Loader=Loader, **kwds):
---
> def load_all(stream, Loader=Loader):
80c80
< loader = Loader(stream, **kwds)
---
> loader = Loader(stream)
constructor.py
$ diff constructor.py Original
20,21c20
< def __init__(self, object_pairs_hook=dict):
< self.object_pairs_hook = object_pairs_hook
---
> def __init__(self):
27,29d25
< def create_object_hook(self):
< return self.object_pairs_hook()
<
54,55c50,51
< self.constructed_objects = self.create_object_hook()
< self.recursive_objects = self.create_object_hook()
---
> self.constructed_objects = {}
> self.recursive_objects = {}
129c125
< mapping = self.create_object_hook()
---
> mapping = {}
400c396
< data = self.create_object_hook()
---
> data = {}
595c591
< dictitems = self.create_object_hook()
---
> dictitems = {}
602c598
< dictitems = value.get('dictitems', self.create_object_hook())
---
> dictitems = value.get('dictitems', {})
loader.py
$ diff loader.py Original
13c13
< def __init__(self, stream, **constructKwds):
---
> def __init__(self, stream):
18c18
< BaseConstructor.__init__(self, **constructKwds)
---
> BaseConstructor.__init__(self)
23c23
< def __init__(self, stream, **constructKwds):
---
> def __init__(self, stream):
28c28
< SafeConstructor.__init__(self, **constructKwds)
---
> SafeConstructor.__init__(self)
33c33
< def __init__(self, stream, **constructKwds):
---
> def __init__(self, stream):
38c38
< Constructor.__init__(self, **constructKwds)
---
> Constructor.__init__(self)
https://stackoverflow.com/questions/5121931
复制相似问题