2016-10-05 2 views
1

私は、豊富なリストを持つ深くネストされたデータ構造を持っています。私はすべての内容を表示する代わりにリストを数えたいと思う。JSONEncoderはリストを処理していません

class SummaryJSONEncoder(json.JSONEncoder): 
    """ 
    Simple extension to JSON encoder to handle date or datetime objects 
    """ 
    def default(self, obj): 
     func = inspect.currentframe().f_code 
     logger.info("%s in %s:%i" % ( 
      func.co_name, 
      func.co_filename, 
      func.co_firstlineno 
     )) 
     logger.info('default %s', type(obj)) 
     if isinstance(obj, (datetime.datetime, datetime.date,)): 
      return obj.isoformat() 
     if isinstance(obj, (list, tuple, set,)): 
      return "count(%s)" % len(obj) 
     else: 
      logger.info('Falling back for %s', type(obj)) 
      return super(SummaryJSONEncoder, self).default(obj) 
    def encode(self, obj): 
     func = inspect.currentframe().f_code 
     logger.info("%s in %s:%i" % ( 
      func.co_name, 
      func.co_filename, 
      func.co_firstlineno 
     )) 
     return super(SummaryJSONEncoder, self).encode(obj) 

セットは正しくエンコードされているように見えますが、リストとタプルは私の意志に屈することはありません。

>>> json.dumps({'hello': set([]), 'world': [1,2,3], 'snot': (1,2,3,), 'time': datetime.datetime.now()}, indent=4, cls=SummaryJSONEncoder) 
2016-10-05 14:07:42,786 (9296) __main__ INFO - encode in <pyshell#56>:20 
2016-10-05 14:07:42,789 (9296) __main__ INFO - default in <pyshell#56>:5 
2016-10-05 14:07:42,792 (9296) __main__ INFO - default <type 'set'> 
2016-10-05 14:07:42,793 (9296) __main__ INFO - default in <pyshell#56>:5 
2016-10-05 14:07:42,796 (9296) __main__ INFO - default <type 'datetime.datetime'> 
'{\n "world": [\n  1, \n  2, \n  3\n ], \n "hello": "count(0)", \n "snot": [\n  1, \n  2, \n  3\n ], \n "time": "2016-10-05T14:07:42.786000"\n}' 
>>> 

リストやタプルは他の場所で処理され、デフォルトのメソッドには渡されないようですが、わかりません。誰もこれを前にする必要がありましたか?

答えて

0

は、このコードのトレースは

class SummaryJSONEncoder(json.JSONEncoder): 
""" 
Simple extension to JSON encoder to handle date or datetime objects 
""" 
def default(self, obj): 
    if isinstance(obj, (datetime.datetime, datetime.date,)): 
     return obj.isoformat() 
    if isinstance(obj, (list, tuple, set,)): 
     return "count(%s)" % len(obj) 
    else: 
     return super(SummaryJSONEncoder, self).default(obj) 
def _iterencode_list(self, obj, x): 
    if isinstance(obj, (list, tuple, set,)): 
     return self.default(obj) 
    return super(SummaryJSONEncoder, self)._iterencode_list(obj, x) 

で動作しているようです。

私はこれが

:-)誰かを役に立てば幸い
json.dumps({'hello': set([]), 'world': [1,2,3], 'snot': (1,2,3,), 'time': datetime.datetime.now()}, indent=4, cls=SummaryJSONEncoder) 
2016-10-05 14:50:10,785 (9296) __main__ INFO - default in <pyshell#73>:5 
2016-10-05 14:50:10,788 (9296) __main__ INFO - default <type 'list'> 
2016-10-05 14:50:10,792 (9296) __main__ INFO - default in <pyshell#73>:5 
2016-10-05 14:50:10,796 (9296) __main__ INFO - default <type 'set'> 
2016-10-05 14:50:10,799 (9296) __main__ INFO - default in <pyshell#73>:5 
2016-10-05 14:50:10,802 (9296) __main__ INFO - default <type 'tuple'> 
2016-10-05 14:50:10,806 (9296) __main__ INFO - default in <pyshell#73>:5 
2016-10-05 14:50:10,811 (9296) __main__ INFO - default <type 'datetime.datetime'> 
'{\n "world": count(3), \n "hello": "count(0)", \n "snot": count(3), \n "time": "2016-10-05T14:50:10.785000"\n}' 

関連する問題