我希望将JSONEncoder
扩展为调用对象的__json__
,以将其转换为可序列化的内容。
我试过这个:
import json
class Foo(object):
def __json__(self):
return dict(a=1, b=2)
class MyJSONEncoder(json.JSONEncoder):
"""
Use __json__ attr or callable of object for JSON serialization.
"""
def default(self, o):
if hasattr(o, '__json__'):
if callable(o.__json__):
o = o.__json__()
else:
o = o.__json__
return super(MyJSONEncoder, self).default(o)
json.dumps(Foo(), cls=MyJSONEncoder)
得到这个:
Traceback (most recent call last):
File "./foo.py", line 20, in <module>
json.dumps(Foo(), cls=MyJSONEncoder)
File "/usr/lib64/python2.7/json/__init__.py", line 250, in dumps
sort_keys=sort_keys, **kw).encode(obj)
File "/usr/lib64/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib64/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "./foo.py", line 18, in default
return super(MyJSONEncoder, self).default(o)
File "/usr/lib64/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: {'a': 1, 'b': 2} is not JSON serializable
答案 0 :(得分:1)
我发现了我的错误:
class MyJSONEncoder(DjangoJSONEncoder):
"""
Use __json__ attr or callable of object for JSON serialization.
"""
def default(self, o):
if hasattr(o, '__json__'):
if callable(o.__json__):
return o.__json__() # <----- here
else:
return o.__json__ # <-------- and here
return super(MyJSONEncoder, self).default(o)
初始实现错误地将o.__json__
结果链传递给父default()
,并假设default()
应返回序列化对象..这不是&# 39;它是如何运作的。它需要返回可序列化的对象。
json/encoder.py
的来源总结了这一点:
要扩展它以识别其他对象,子类并使用另一个方法实现
.default()
方法,如果可能的话,该方法返回o
的可序列化对象,否则它应该调用超类实现(以提升{{ 1}})。