Skip to content

Instantly share code, notes, and snippets.

@jsbueno
Last active March 29, 2018 08:11
Show Gist options
  • Save jsbueno/9b2ea63fb16b84658281ec29b375283e to your computer and use it in GitHub Desktop.
Save jsbueno/9b2ea63fb16b84658281ec29b375283e to your computer and use it in GitHub Desktop.
Helpers to serialize/de-serialize generic Python objects as JSON
"""Custom JSON encoder and Decoder classes to work with general Python classes
Pass these as the `cls` argument to json.dump and json.load to enable
the serialization of most Python defined "well behaved" objects
directly as JSON.
Ref.: http://stackoverflow.com/questions/43092113/create-a-class-that-support-json-serialization-for-use-with-celery/43093361#43093361
"""
import json
class GenericJSONEncoder(json.JSONEncoder):
def default(self, obj):
try:
return super().default(obj)
except TypeError:
pass
cls = type(obj)
result = {
'__custom__': True,
'__module__': cls.__module__,
'__name__': cls.__name__,
'data': obj.__dict__ if not hasattr(cls, '__json_encode__') else obj.__json_encode__
}
return result
class GenericJSONDecoder(json.JSONDecoder):
def decode(self, str):
result = super().decode(str)
if not isinstance(result, dict) or not result.get('__custom__', False):
return result
import sys
module = result['__module__']
if not module in sys.modules:
__import__(module)
cls = getattr(sys.modules[module], result['__name__'])
if hasattr(cls, '__json_decode__'):
return cls.__json_decode__(result['data'])
instance = cls.__new__(cls)
instance.__dict__.update(result['data'])
return instance
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment