Home > Software design >  How to convert nested classes to json or dict?
How to convert nested classes to json or dict?

Time:02-28

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"
    }
}
  • Related