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.