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]
"""
View Code

工具类:

点击查看Github源码

# -* 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/ 

posted @ 2018-09-01 19:56  情猿  阅读(2488)  评论(0编辑  收藏  举报