I am trying to create a JSON string representation of a class instance and having difficulty. Let's say the class is built like this:
class testclass:
value1 = "a"
value2 = "b"
A call to the json.dumps is made like this:
t = testclass()
json.dumps(t)
It is failing and telling me that the testclass is not JSON serializable.
TypeError: <__main__.testclass object at 0x000000000227A400> is not JSON serializable
I have also tried using the pickle module :
t = testclass()
print(pickle.dumps(t, pickle.HIGHEST_PROTOCOL))
And it gives class instance information but not a serialized content of the class instance.
b'\x80\x03c__main__\ntestclass\nq\x00)\x81q\x01}q\x02b.'
What am I doing wrong?
You can specify the
default
named parameter in thejson.dumps()
function:Explanation:
Form the docs (2.7, 3.6):
(Works on Python 2.7 and Python 3.x)
Note: In this case you need
instance
variables and notclass
variables, as the example in the question tries to do. (I am assuming the asker meantclass instance
to be an object of a class)I learned this first from @phihag's answer here. Found it to be the simplest and cleanest way to do the job.
Using jsonpickle
The basic problem is that the JSON encoder
json.dumps()
only knows how to serialize a limited set of object types by default, all built-in types. List here: https://docs.python.org/3.3/library/json.html#encoders-and-decodersOne good solution would be to make your class inherit from
JSONEncoder
and then implement theJSONEncoder.default()
function, and make that function emit the correct JSON for your class.A simple solution would be to call
json.dumps()
on the.__dict__
member of that instance. That is a standard Pythondict
and if your class is simple it will be JSON serializable.The above approach is discussed in this blog posting:
Serializing arbitrary Python objects to JSON using __dict__
NOTE: I have edited this answer; the original version only discussed the
.__dict__
serializing approach.There are some good answers on how to get started on doing this. But there are some things to keep in mind:
__slots__
instead of__dict__
?json-tricks is a library (that I made and others contributed to) which has been able to do this for quite a while. For example:
You'll get your instance back. Here the json looks like this:
If you like to make your own solution, you might look at the source of
json-tricks
so as not to forget some special cases (like__slots__
).It also does other types like numpy arrays, datetimes, complex numbers; it also allows for comments.
Here are two simple functions for serialization of any non-sophisticated classes, nothing fancy as explained before.
I use this for configuration type stuff because I can add new members to the classes with no code adjustments.
There's one way that works great for me that you can try out:
json.dumps()
can take an optional parameter default where you can specify a custom serializer function for unknown types, which in my case looks likeFirst two ifs are for date and time serialization and then there is a
obj.__dict__
returned for any other object.the final call looks like:
It's especially good when you are serializing a collection and you don't want to call
__dict__
explicitly for every object. Here it's done for you automatically.So far worked so good for me, looking forward for your thoughts.