简体   繁体   中英

JSON serialize objects in Python in list / diconary

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?

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)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM