I have a class defined like this
class A:
def __init__(self):
self.item1 = None
def __repr__(self):
return str(self.__dict__)
when I do:
>>> import simplejson
>>> myA = A()
>>> simplejson.dumps(myA)
TypeError: {'item1': None} is not JSON serializable
I can't find the reason why.
Do I need to add any particular method to A for simplejson to serialize my class object?
Use toJSON() Method to make class JSON serializable So we don't need to write custom JSONEncoder. This new toJSON() serializer method will return the JSON representation of the Object. i.e., It will convert custom Python Object to JSON string.
Working With JSON Data in Python The json module exposes two methods for serializing Python objects into JSON format. dump() will write Python data to a file-like object. We use this when we want to serialize our Python data to an external JSON file. dumps() will write Python data to a string in JSON format.
The Python "TypeError: Object of type set is not JSON serializable" occurs when we try to convert a set object to a JSON string. To solve the error, convert the set to a list before serializing it to JSON, e.g. json. dumps(list(my_set)) . Here is an example of how the error occurs.
Json namespace provides functionality for serializing to and deserializing from JavaScript Object Notation (JSON). Serialization is the process of converting the state of an object, that is, the values of its properties, into a form that can be stored or transmitted.
You can't serialize arbitrary objects with simplejson
. You need to pass a default
and object_hook
to dump
and load
. Here's an example:
class SerializerRegistry(object):
def __init__(self):
self._classes = {}
def add(self, cls):
self._classes[cls.__module__, cls.__name__] = cls
return cls
def object_hook(self, dct):
module, cls_name = dct.pop('__type__', (None, None))
if cls_name is not None:
return self._classes[module, cls_name].from_dict(dct)
else:
return dct
def default(self, obj):
dct = obj.to_dict()
dct['__type__'] = [type(obj).__module__,
type(obj).__name__]
return dct
registry = SerializerRegistry()
@registry.add
class A(object):
def __init__(self, item1):
self.item1 = item1
def __repr__(self):
return str(self.__dict__)
def to_dict(self):
return dict(item1=self.item1)
@classmethod
def from_dict(cls, dct):
return cls(**dct)
s = json.dumps(A(1), default=registry.default)
a = json.loads(s, object_hook=registry.object_hook)
This results in this:
>>> s
'{"item1": 1, "__type__": ["__main__", "A"]}'
>>> a
{'item1': 1}
But what you really need is a function default
that creates dictionary from the objects that you wish to serialize, and a function object_hook
that returns an object (of the correct type) when it is given a dictionary if a dictionary isn't enough. The best approach is to have methods on the serializable classes that create a dict from the object and that construct it back, and also to have a mapping that recognizes to which class the dictionaries belong.
You can also add an identifier to the classes to be used as an index for _classes
. This way you wouldn't have issues if you have to move a class.
According to the json module docs (simplejson was adopted as json in Python 2.6), you need to extend the json.JSONEncoder
class, overriding its default method to translate your object into a type that can be serialised. There doesn't appear to be a method that it looks for on your object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With