Last active
November 12, 2021 12:23
-
-
Save hoshiyosan/7a23e4c2c6efe14d1d6cfc18c8b9b098 to your computer and use it in GitHub Desktop.
Dataclass serialization / deserialization in Python
This file contains hidden or 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 dataclasses | |
import importlib | |
import json | |
from typing import Any | |
def dataclass_from_dict(d: dict): | |
try: | |
modulepath, classname = d.pop("__class__").rsplit(".", 1) | |
module = importlib.import_module(modulepath) | |
Class = getattr(module, classname) | |
return Class(**d) | |
except: | |
return d | |
class DataclassEncoder(json.encoder.JSONEncoder): | |
def default(self, o: Any): | |
if dataclasses.is_dataclass(o): | |
d = {f.name: getattr(o, f.name) for f in dataclasses.fields(o)} | |
d["__class__"] = o.__class__.__module__ + "." + o.__class__.__name__ | |
return d | |
return o | |
class DataclassDecoder(json.decoder.JSONDecoder): | |
def __init__(self, *args, **kwargs): | |
super().__init__(*args, object_hook=dataclass_from_dict, **kwargs) |
This file contains hidden or 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
from dataclasses_utils import | |
@dataclasses.dataclass | |
class Contact: | |
email: str | |
address: str | |
@dataclasses.dataclass | |
class Account: | |
username: str | |
contact: str | |
if __name__ == "__main__": | |
# create and display an account dataclass | |
account = Account( | |
username="toto", | |
contact=Contact(email="[email protected]", address="123 Main Street, New York, NY 10030"), | |
) | |
print(">>>", account) | |
# compute and display dataclass dump | |
account_data = json.dumps(account, indent=4, cls=DataclassEncoder) | |
print(account_data) | |
# compute and display loaded json, with dataclass automatically deserialized into proper Python object | |
print(json.loads(account_data, cls=DataclassDecoder)) |
This file contains hidden or 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
# This is the output you can expect when running `python main.py` | |
>>> Account(username='toto', contact=Contact(email='[email protected]', address='123 Main Street, New York, NY 10030')) | |
>>> { | |
"username": "toto", | |
"contact": { | |
"email": "[email protected]", | |
"address": "123 Main Street, New York, NY 10030", | |
"__class__": "__main__.Contact" | |
}, | |
"__class__": "__main__.Account" | |
} | |
>>> Account(username='toto', contact=Contact(email='[email protected]', address='123 Main Street, New York, NY 10030')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment