pyyaml “有序”解析/生成yaml
背景:
在使用pyyaml时发现,当由字典dump成yaml文件时,顺序会被打乱,如果将字典改成OrderDict有序“字典”,则在dump的时候生成的结构会带入OrderDict的信息,所以本文提供的工具类来解决这个问题。
例子如下:点击查看Github代码
# -* encoding:utf-8 -*- from collections import OrderedDict import yaml import yamlparser # 测试json.load path = 'load.yml' result = yaml.load(open(path)) """ result: {'p2': 2, 'p3': 3, 'p1': 1, 'p4': 4, 'p5': 5} """ dumpfile = open('dump.yml', 'w') # 测试json.dump dict pydir = {} cdir = {} pydir['c'] = cdir cdir['rep1'] = 1 cdir['csd2'] = 2 cdir['fs3'] = 3 cdir['asd4'] = 4 cdir['ioweq5'] = 5 cdir['asd6'] = 6 res = yaml.dump(pydir, dumpfile, default_flow_style=False) """ res: c: asd4: 4 asd6: 6 csd2: 2 fs3: 3 ioweq5: 5 rep1: 1 """ # 测试json.dump OrderDict pydir2 = {} cdir2 = OrderedDict() pydir2['c'] = cdir2 cdir2['rep1'] = 1 cdir2['csd2'] = 2 cdir2['fs3'] = 3 cdir2['asd4'] = 4 cdir2['ioweq5'] = 5 cdir2['asd6'] = 6 orderResult = yaml.dump(pydir2, dumpfile) """ orderResult: c: asd4: 4 asd6: 6 csd2: 2 fs3: 3 ioweq5: 5 rep1: 1 c: !!python/object/apply:collections.OrderedDict - - [rep1, 1] - [csd2, 2] - [fs3, 3] - [asd4, 4] - [ioweq5, 5] - [asd6, 6] """
工具类:
# -* encoding:utf-8 -*- from collections import OrderedDict import yaml import os def ordered_yaml_load(yaml_path, Loader=yaml.Loader, object_pairs_hook=OrderedDict): class OrderedLoader(Loader): pass def construct_mapping(loader, node): loader.flatten_mapping(node) return object_pairs_hook(loader.construct_pairs(node)) OrderedLoader.add_constructor( yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, construct_mapping) with open(yaml_path) as stream: return yaml.load(stream, OrderedLoader) def ordered_yaml_dump(data, stream=None, Dumper=yaml.SafeDumper, **kwds): class OrderedDumper(Dumper): pass def _dict_representer(dumper, data): return dumper.represent_mapping( yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, data.items()) OrderedDumper.add_representer(OrderedDict, _dict_representer) return yaml.dump(data, stream, OrderedDumper, **kwds)
from:http://www.axiaoxin.com/article/220/