5

So i have the following objects:

import os
import sys
import json

class ComplexEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, P):
            return json.dumps(obj.__dict__)
        # Let the base class default method raise the TypeError
        return json.JSONEncoder.default(self, obj)

class P(object):
    def __init__(self):
        self.name = "Unknown"
        self.id = 1
        self.lst = []

    def showName(self):
        print(self.name)
        for item in self.lst:
            item.showName()

    def add(self, p):
        self.lst.append(p)

    def serialize(self):
        return json.dumps(self, cls=ComplexEncoder)

class PFirst(P):
    def __init__(self):
        P.__init__(self)
        self.name = "First"
        self.id = 2

p1 = PFirst()
p1.showName()

p = P()
p.add(p1)
p.showName()

print(p.serialize())

I want to make a json which reprezents the attributes of object p but i receive the following error:

TypeError: <__main__.PFirst object at 0x000002AA287F1438> is not JSON serializable

Can someone please help me?

1 Answer 1

6
        return json.dumps(obj.__dict__)

You are calling json.dumps with the default encoder again, which surely don't know how to deal with P objects. If you do want to call json.dumps, use:

        return json.dumps(obj.__dict__, cls=type(self))
#                                     ^~~~~~~~~~~~~~~~

However! If the print the result, we see the result is double-encoded as a string:

"{\"name\": \"Unknown\", \"id\": 1, \"lst\": [\"{\\\"name\\\": \\\"First\\\", \\\"id\\\": 2, \\\"lst\\\": []}\"]}"

If you check the ComplexEncoder example, and also the documentation of default(), we will note that it should return a "serializable object", not the serialized string. So you should really write:

class ComplexEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, P):
            return obj.__dict__         # <-----
        return json.JSONEncoder.default(self, obj)

Output:

{"name": "Unknown", "id": 1, "lst": [{"name": "First", "id": 2, "lst": []}]}
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.