问题描述
我正在尝试将对象的__dict__
序列化为JSON,该方法工作正常,直到将对象追加到第一个对象的instance属性之一为止.
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__)
第二次打电话给dumps
时,我得到了以下TypeError
:
When calling for the second time dumps
, I got the following TypeError
:
TypeError: {"y": "Y", "x": "X"} is not JSON serializable
我不明白为什么为什么一直收到此错误,却看不到为什么无法序列化为JSON.
I don't understand why I keep getting this error while I can't see why this is not serializable to JSON.
推荐答案
这是因为B
的实例不是简单类型.因为您为B
提供了__repr__
方法,所以实例被打印为 printed (因为它是JSON表示形式),但它本身并不是受支持的JSON类型.
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.
删除__repr__
方法,回溯就不那么混乱了:
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
使用default
关键字参数对自定义对象进行编码:
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)
演示:
>>> 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"}]}'
这篇关于Python将对象列表序列化为JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!