那是因为B
的实例不是一个简单类型。因为您给了B
一个__repr__
方法,所以该实例会被打印为它的JSON表示,但它本身不是支持的JSON类型。
移除__repr__
方法,回溯信息就不会那么混乱:
>>> 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
关键字参数来编码自定义对象:
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"}]}'
__repr__
来序列化对象,但是没有__repr__
确实更清晰明了。 - evuez__repr__
。 OP 尝试通过给B
的实例提供一个__repr__
方法使它们可以被序列化为 JSON,但是这种方法在这里根本不起作用。 - Martijn Pietersencode
逻辑/过程,而无需扩展JsonEncoder?(我假设json在对象上没有寻找这样的属性?) - TjorriemorrieJSONEncoder
,因为确实没有编码器要查找的属性。Pyramid项目扩展了他们的编码器以查找__json__
方法,但同样需要自定义编码器。 - Martijn Pieters