Last active
January 25, 2023 11:08
-
-
Save oglops/c70fb69eef42d40bed06 to your computer and use it in GitHub Desktop.
write to and load from yaml file with OrderedDict
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
try: | |
# for python newer than 2.7 | |
from collections import OrderedDict | |
except ImportError: | |
# use backport from pypi | |
from ordereddict import OrderedDict | |
import yaml | |
# try to use LibYAML bindings if possible | |
try: | |
from yaml import CLoader as Loader, CDumper as Dumper | |
except ImportError: | |
from yaml import Loader, Dumper | |
from yaml.representer import SafeRepresenter | |
_mapping_tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG | |
def dict_representer(dumper, data): | |
return dumper.represent_dict(data.items()) | |
def dict_constructor(loader, node): | |
return OrderedDict(loader.construct_pairs(node)) | |
Dumper.add_representer(OrderedDict, dict_representer) | |
Loader.add_constructor(_mapping_tag, dict_constructor) | |
Dumper.add_representer(str, | |
SafeRepresenter.represent_str) | |
Dumper.add_representer(unicode, | |
SafeRepresenter.represent_unicode) | |
# output = yaml.dump(data, Dumper=Dumper, default_flow_style=False) | |
# data = yaml.load(stream, Loader=Loader) | |
# abc: | |
# x: | |
# 0: null | |
# y: | |
# 1: null | |
yml_dict = OrderedDict( | |
abc=OrderedDict( | |
[('x', OrderedDict([(0, None)])), ('y', OrderedDict([(1, None)]))])) | |
import json | |
print(json.dumps(yml_dict, indent=2)) | |
# dump ordereddict to yaml | |
output = yaml.dump(yml_dict, Dumper=Dumper, default_flow_style=False) | |
print output | |
# directly write to a file object to save memory. | |
with open('result.yml', 'w') as f: | |
yaml.dump(yml_dict, f, default_flow_style=False) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import yaml | |
from yaml import SafeDumper, Dumper, SafeLoader | |
from collections import OrderedDict | |
class OrderedDumper(SafeDumper): | |
def __init__(self, *args, **kwargs): | |
super(OrderedDumper, self).__init__(*args, **kwargs) | |
represent_dict_order = lambda self, data: self.represent_mapping(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, data.items()) | |
self.add_representer(OrderedDict, represent_dict_order) | |
data = OrderedDict([(2, 'b'), (1, 'a'), (3, [{'children': [{4: 'c'}, {5: 'd'}]}])]) | |
print(yaml.dump(data, Dumper=OrderedDumper)) | |
class OrderedLoader(SafeLoader): | |
def __init__(self, *args, **kwargs): | |
super(OrderedLoader, self).__init__(*args, **kwargs) | |
construct_dict_order = lambda self, data: OrderedDict(self.construct_pairs(data)) | |
self.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, construct_dict_order) | |
with open('test.yaml') as f: | |
d = yaml.load(f, Loader=OrderedLoader) | |
print(d) | |
# pretty print ordered dict | |
import json | |
print(json.dumps(d, indent=4)) |
Very useful. Thank you!
Very useful for Python 2.7.
Since unicode is removed from python 3, I have faced an error at Dumper.add_representer(unicode, SafeRepresenter.represent_unicode). I have removed that line. But the generated yaml file contains !!python/tuple and &id001 here and there. Please help me in resolving this
nice! I just need the loader part, so this is very simple (compared to some other approaches..)
For saving OrderedDict files I had to change iteritems() to items()
from yaml import CDumper as Dumper
def dict_representer(dumper, data):
return dumper.represent_dict(data.items())
Dumper.add_representer(OrderedDict, dict_representer)
s = yaml.dump(data, explicit_start=True, Dumper=Dumper)
The original code changes yaml behavior globally, if you are working on a library, a better approach is to customize dumper/loader subclass
https://ilmvfx.wordpress.com/2022/07/20/yaml-json-tree-serialize-keep-order/
Thank you very much! Very useful!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks!