我正在尝试创建自己的自定义编码器,主要重用JSONEncoder行为:
BinaryJSONEncoder(JSONEncoder):
def _iterencode(self, o, markers):
sys.stderr.write("Calling custom _iterencode\n")
try:
return JSONEncoder._iterencode(self, o, markers)
except UnicodeDecodeError:
sys.stderr.write("Got exception\n")
return ""
但是,我仍然得到一个未处理的UnicodeDecodeError,因为一旦调用了_iterencode方法,它就会在返回之前循环通过它的生成器。奇怪的是异常来自_iterencode方法,但我的方法在返回堆栈中无处可去!但我的函数被调用,因为“调用自定义_iterencode”消息在Apache error_log中出现。如果不从头开始实施整个方法,我该如何解决这个问题呢?
这是堆栈:
Traceback (most recent call last):
File "/var/www/radiator/cgi-bin/ldapsearch.py", line 108, in <module>
res.body(json.dumps(res_data, cls=BinaryJSONEncoder))
File "/usr/lib64/python2.6/json/__init__.py", line 237, in dumps
**kw).encode(obj)
File "/usr/lib64/python2.6/json/encoder.py", line 367, in encode
chunks = list(self.iterencode(o))
File "/usr/lib64/python2.6/json/encoder.py", line 306, in _iterencode
for chunk in self._iterencode_list(o, markers):
File "/usr/lib64/python2.6/json/encoder.py", line 204, in _iterencode_list
for chunk in self._iterencode(value, markers):
File "/usr/lib64/python2.6/json/encoder.py", line 306, in _iterencode
for chunk in self._iterencode_list(o, markers):
File "/usr/lib64/python2.6/json/encoder.py", line 204, in _iterencode_list
for chunk in self._iterencode(value, markers):
File "/usr/lib64/python2.6/json/encoder.py", line 309, in _iterencode
for chunk in self._iterencode_dict(o, markers):
File "/usr/lib64/python2.6/json/encoder.py", line 275, in _iterencode_dict
for chunk in self._iterencode(value, markers):
File "/usr/lib64/python2.6/json/encoder.py", line 306, in _iterencode
for chunk in self._iterencode_list(o, markers):
File "/usr/lib64/python2.6/json/encoder.py", line 204, in _iterencode_list
for chunk in self._iterencode(value, markers):
File "/usr/lib64/python2.6/json/encoder.py", line 294, in _iterencode
yield encoder(o)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xc3 in position 2: invalid continuation byte
答案 0 :(得分:0)
似乎解决此问题的唯一可行方法是再次实现整个函数,使用二进制数据处理程序:
来自json.encoder import encode_basestring_ascii,encode_basestring
class BinaryJSONEncoder(JSONEncoder):
def _iterencode(self, o, markers=None):
if isinstance(o, str):
try:
o = unicode(o, "utf8")
except UnicodeDecodeError:
o = base64.b64encode(o)
if isinstance(o, basestring):
if self.ensure_ascii:
encoder = encode_basestring_ascii
else:
encoder = encode_basestring
_encoding = self.encoding
if (_encoding is not None and isinstance(o, str)
and not (_encoding == 'utf-8')):
o = o.decode(_encoding)
yield encoder(o)
elif o is None:
yield 'null'
elif o is True:
yield 'true'
elif o is False:
yield 'false'
elif isinstance(o, (int, long)):
yield str(o)
elif isinstance(o, float):
yield floatstr(o, self.allow_nan)
elif isinstance(o, (list, tuple)):
for chunk in self._iterencode_list(o, markers):
yield chunk
elif isinstance(o, dict):
for chunk in self._iterencode_dict(o, markers):
yield chunk
else:
if markers is not None:
markerid = id(o)
if markerid in markers:
raise ValueError("Circular reference detected")
markers[markerid] = o
for chunk in self._iterencode_default(o, markers):
yield chunk
if markers is not None:
del markers[markerid]
我理解抛出异常时收益率退出的问题,但为什么不能在没有它然后只调用超类方法之后调用超类方法呢?