JSONEncoder不处理列表

时间:2016-10-05 13:16:37

标签: python json list set encode

我有一个包含大量列表的深层嵌套数据结构。我想计算列表而不是显示所有内容。

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}'
>>>

我无法分辨,但看起来列表和元组在别处处理,而不是传递给默认方法。有没有人需要这样做呢?

1 个答案:

答案 0 :(得分: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}'

我希望这有助于某人: - )