I have class of classes as below:
class Base:
def __init__(self):
self.var1 = “variable”
class Child:
def __init__(self):
self.base = Base()
self.var2 = False
class RootChild:
def __init__(self):
self.child = Child()
self.var3 = “variable”
self.base = Base()
I want to save an instance of ‘RootChild’ with all fields of it represented in json. There are a lot of topics about this task, but I could not understand their differences and use cases. What are most pythonic solutions to this problem?
CodePudding user response:
Your mileage will vary - from using a "serializer" strategy: a layer of mechanisms that will know how to map from your classes to Json and back, which can be a lot of work (to the point of hand-describing each field that should be serialized/unserialized) - https://docs.pylonsproject.org/projects/colander/en/latest/
Or you could build a custom JSON encoder that will just check if it is a known class and then return a dict with all its fields (which can be extracted automatically by introspection) - (check the example to extend the encoder here: https://docs.python.org/3/library/json.html )
Any way there are lots of trade-offs and differing level of work - if you plan to read the JSON back in Python apps which have the same classes, you could use "jsonpickle" - it will add extra meta-data to your JSON, but will ensure round tripping of all your objects exactly as they are: https://jsonpickle.github.io/
Without using any other lib, and assuming you just need to export your classes, the custom encoder strategy can be somewhat simple:
import json
class SimpleObject(json.JSONEncoder):
def default(self, obj):
if hasattr(obj, "__dict__"):
return {key:value for key, value in obj.__dict__.items() if not key.startswith("_")}
return super().default(obj)
a = RootChild()
And on the interactive environment:
In [52]: a = RootChild()
In [53]: print(json.dumps(a, cls=SimpleObject, indent=4))
{
"child": {
"base": {
"var1": "variable"
},
"var2": false
},
"var3": "variable",
"base": {
"var1": "variable"
}
}