yaml 按顺序 load,dump

当你有一个 map.里面有dict,list各种的时候, 如果你用 yaml.load,yaml.dump,你会发现他的顺序有变了, 当你不洗碗他变的时候, 怎么办??

  1. from collections import OrderedDict
  2. import yaml
  3. def ordered_yaml_load(yaml_path, Loader=yaml.Loader,
  4. object_pairs_hook=OrderedDict):
  5. class OrderedLoader(Loader):
  6. pass
  7. def construct_mapping(loader, node):
  8. loader.flatten_mapping(node)
  9. return object_pairs_hook(loader.construct_pairs(node))
  10. OrderedLoader.add_constructor(
  11. yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
  12. construct_mapping)
  13. with open(yaml_path) as stream:
  14. return yaml.load(stream, OrderedLoader)
  15. def ordered_yaml_dump(data, filename, Dumper=yaml.SafeDumper):
  16. class OrderedDumper(Dumper):
  17. pass
  18. def _dict_representer(dumper, data):
  19. return dumper.represent_mapping(
  20. yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, data.items())
  21. ## 这里是 把 生成文件里的 “null” 转为 “”
  22. def represent_none(self,_):
  23. return self.represent_scalar('tag:yaml.org,2002:null','')
  24. stream = None
  25. with open(filename, "w") as stream:
  26. OrderedDumper.add_representer(OrderedDict, _dict_representer)
  27. OrderedDumper.add_representer(type(None), represent_none)
  28. yaml.dump(data,
  29. stream,
  30. OrderedDumper,
  31. default_flow_style=False,
  32. encoding='utf-8',
  33. allow_unicode=True)
  34. ### 使用
  35. kv_conf_tmpl = ordered_yaml_load("./kkkk.conf")
  36. ordered_yaml_dump(kv_conf_tmpl, "./after_kk.conf")

yaml.dump 有个坑, 当你文件是none,它会打印出“null”

这就很烦了。所以,需要去掉。 (上面的例子里也有介绍)

def represent_none(self, _):
    return self.represent_scalar('tag:yaml.org,2002:null', '')

yaml.add_representer(type(None), represent_none)

参考链接(https://stackoverflow.com/questions/37200150/can-i-dump-blank-instead-of-null-in-yaml-pyyaml?answertab=active#tab-top)