0

I am trying to store information about a class in a file. From what I've read, the data is typically converted into a dictionary using instance.__dict__. But the problem is my class contains classes nested inside. For example:

Class1:
    # Example data members
    data = None
    a = 0
    b = 0
    def __init__(self, data, a, b):
        self.data = data
        self.a = a
        self.b = b

Class2:
    x = 0
    y = 0
    def __init__(self, x, y):
        self.x = x
        self.y = y

nested_class = Class2(5, 10)
exterior_class = Class1(nested_class, 10, 15)

Now for the sake of keeping things clear, I am going to refer to the example (instead of the data I am actually working with because its more complicated). If I want to save Class1 in a .json, I cannot use json.dump because it cannot convert the class into a storage format. You can use the above method I mentioned but it won't convert the Class2 into a dictionary. Does anybody know of a better way to solve this issue without having to individually convert each nested class into a dictionary and then back when I need to use them as actual classes and not dictionaries (For the record, I have three layers of nested classes in my actual scenario, so an efficient solution will be appreciated)

1 Answer 1

4

You can use the default argument of json.dumps() to get the __dict__ of an attribute that can't be serialized, such as a nested class object.

If specified, default should be a function that gets called for objects that can’t otherwise be serialized. It should return a JSON encodable version of the object or raise a TypeError. If not specified, TypeError is raised.

import json


class Class1:
    # Example data members
    data = None
    a = 0
    b = 0
    def __init__(self, data, a, b):
        self.data = data
        self.a = a
        self.b = b


class Class2:
    x = 0
    y = 0
    def __init__(self, duo, x, y):
        self.duo = duo
        self.x = x
        self.y = y


class Class3:
    def __init__(self, name1, name2):
        self.name1 = name1
        self.name2 = name2


level3 = Class3("John Lennon", "Paul McCartney")
level2 = Class2(level3, 5, 10)
level1 = Class1(level2, 10, 15)

def to_serializable(val):
    if hasattr(val, '__dict__'):
        return val.__dict__
    return val

print(json.dumps(level1.__dict__, default=to_serializable))

Output (pretty printed with an indentation of 4):

{
    "data": {
        "duo": {
            "name1": "John Lennon",
            "name2": "Paul McCartney"
        },
        "x": 5,
        "y": 10
    },
    "a": 10,
    "b": 15
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.