I am trying to serialize to JSON the __dict__
of an object, which is working fine, until I append objects to one of the instance attribute of my first object:
from json import dumps
class A(object):
def __init__(self):
self.b_list = []
class B(object):
def __init__(self):
self.x = 'X'
self.y = 'Y'
def __repr__(self):
return dumps(self.__dict__)
a = A()
print dumps(a.__dict__) # works fine
a.b_list.append(B())
print dumps(a.__dict__)
When calling for the second time dumps
, I got the following TypeError
:
TypeError: {"y": "Y", "x": "X"} is not JSON serializable
I don't understand why I keep getting this error while I can't see why this is not serializable to JSON.
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.
Use json. dumps() to serialize a list into a JSON object. Use json. dumps(list) to serialize list into a JSON string.
You can convert any Python object to a JSON string and write JSON to File using json. dumps() function and file. write() function respectively.
The JSON encoder implemented in the dump() and dumps() methods can serialize only a few basic object types. These are dictionaries, lists, strings, integers, floats, Booleans, and None.
That's because instances of B
are not a simple type. Because you gave B
a __repr__
method, the instance is printed as it's JSON representation, but it is not itself a supported JSON type.
Remove the __repr__
method and the traceback is much less confusing:
>>> class A(object):
... def __init__(self):
... self.b_list = []
...
>>> class B(object):
... def __init__(self):
... self.x = 'X'
... self.y = 'Y'
...
>>> a = A()
>>> a.b_list.append(B())
>>>
>>> print dumps(a.__dict__)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/json/__init__.py", line 243, in dumps
return _default_encoder.encode(obj)
File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <__main__.B object at 0x10a753e10> is not JSON serializable
Use the default
keyword argument to encode custom objects:
def encode_b(obj):
if isinstance(obj, B):
return obj.__dict__
return obj
json.dumps(a, default=encode_b)
Demo:
>>> def encode_b(obj):
... if isinstance(obj, B):
... return obj.__dict__
... return obj
...
>>> dumps(a.__dict__, default=encode_b)
'{"b_list": [{"y": "Y", "x": "X"}]}'
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