2014-06-13 22 views
0

我試圖創建大多重用JSONEncoder行爲自己的自定義編碼器_iterencode方法:問題壓倒一切的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

這似乎是解決這個問題的唯一可行的方法是再次實現整體功能,與處理程序的二進制數據:

從json.encoder進口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] 

我明白與產量退出時拋出一個異常的問題,但爲什麼不能superclas那麼在沒有它的情況下會調用它的方法,然後只調用超類方法?