0

I am very new to Python and I have this rather large and complex data structure that is a list of dictionaries with lists of different objects. When I try and convert this to JSON via json.dumps() I get the standard

TypeError: <...> is not JSON serializable

I did some research, and most of the answers point to a standard way of writing a custom encoder, which is fine, I can do that. However, I would like to be able to send my whole data structure to json.dumps() and not loop through everything, figure out what class it is, and build a json object from scratch.

Is there a way to add an encoder/decoder functions to the python class itself, so when I send a complex data structure to json.dumps, the class itself knows what to do.

is there some magic to_json or some way of adding a custom decoder to that class that gets called when the json.dumps runs into it?

1
  • Can you share the json data which you are providing. Commented Feb 14, 2018 at 5:25

2 Answers 2

1

The custom encoder class handles that for you when you use json.dumps(my_object, cls=MyCustomJsonEncoder). Your custom encoder would override the default method, which takes self and the object o to encode; test for the different types that need custom serialization, and pass the rest to the default with super(MyCustomJsonEncoder, self).default(o).

A simple example that I often use is as follows:

class JSONEncoder(json.JSONEncoder):
    """
    Enhancement of base JSONEncoder, also handling these objects:
     * datetime.datetime
     * decimal.Decimal
     * uuid.UUID
    """

    def default(self, o):
        if isinstance(o, Decimal):
            return float(o)
        elif isinstance(o, UUID):
            return str(o)
        elif isinstance(o, datetime):
            return {
                '__type__': 'datetime',
                '__value__': o.isoformat(),
            }
        return super(JSONEncoder, self).default(o)

    @staticmethod
    def dumps(obj):
        return json.dumps(obj, cls=JSONEncoder)
Sign up to request clarification or add additional context in comments.

1 Comment

I am getting a AttributeError: 'super' object has no attribute 'default' I added some logging and it's choking on the type: 'stringmap' what do I do for that?
1

As Steven Wolfe stated in this thread, you may want to look into jsonpickle. This library allows for encoding and decoding of complex Python object.

You could use it this way:

import jsonpickle

f = open(filename, 'w')
encoded_string = jsonpickle.encode(obj)
f.write(encoded_string)
f.close()

And to retrieve the data as Python object, simply use the jsonpickle.decode(encoded_string) method. As the documentation says :

The new object has the same type and data, but essentially is now a copy of the original.

I think that could work well for you.

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.