Skip to content

Instantly share code, notes, and snippets.

@Nicolas-Constanty
Last active July 28, 2022 22:45
Show Gist options
  • Select an option

  • Save Nicolas-Constanty/cd767f7e4b73ed48b6744e671b4b53dc to your computer and use it in GitHub Desktop.

Select an option

Save Nicolas-Constanty/cd767f7e4b73ed48b6744e671b4b53dc to your computer and use it in GitHub Desktop.
json nested object serialization
import json
import typing
from json import JSONEncoder
def _default(self, obj):
return getattr(obj.__class__, "serialize", _default.default)(obj)
_default.default = JSONEncoder().default
JSONEncoder.default = _default
class ISerializable:
def serialize(self) -> str:
d = {k: v for k, v in self.__dict__.items() if not k.startswith("_")}
s = json.dumps(d)
s = s.replace('"{', '{')
s = s.replace('}"', '}')
s = s.replace("\\", "")
return s
@staticmethod
def deserialize(tt, json_string: str) -> 'ISerializable':
t = tt()
json_data = json.loads(json_string)
for k, v in json_data.items():
if isinstance(v, dict):
ct = type(getattr(t, k))
o = ct.deserialize(ct, json.dumps(v))
setattr(t, k, o)
elif isinstance(v, list):
tab = ISerializable.deserialize_list(k, t, v)
setattr(t, k, tab)
else:
setattr(t, k, v)
return t
@staticmethod
def deserialize_list(k, t, v):
tab = []
for e in v:
if isinstance(e, dict):
ct = type(getattr(t, k)[0])
o = ct.deserialize(ct, json.dumps(e))
tab.append(o)
elif isinstance(e, list):
tab.append(ISerializable.deserialize_list(k, t, e))
else:
tab.append(e)
return tab
class TT(ISerializable):
def __init__(self):
self.count = 2
self.o = OMG()
def __str__(self):
return f"TT.{self.count},{self.o}"
class OMG(ISerializable):
def __init__(self):
self.count = 20
def __str__(self):
return f"OMG.{self.count}"
class Test(ISerializable):
name: str
parent: TT
_hidden: int
parent: typing.List[TT]
def __init__(self):
self.name = "toto"
self.parent = TT()
self.parents = [TT(), TT()]
self._hidden = 10
def __str__(self):
pt = ""
for p in self.parents:
pt += str(p)
return f"{self.name},{pt},{self.parent},{self._hidden}"
def main():
t = Test()
print(t)
s = t.serialize()
print(s)
t = Test.deserialize(Test, s)
print(t)
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment