python结构JSON序列化问题

时间:2013-10-26 09:46:55

标签: python json serialization

我有一个缓存字典,为每个密钥存储一个3元素列表:[value, date_created, hits]。缓存通信是通过JSON完成的。缓存中有一个items命令,它将返回所有项目。这是设置缓存方法:

@status
def handle_set(self, key, value):
    self.data[key] = [value, datetime.datetime.now(), 0]
    return

当我有一个非空缓存并且我在其上调用items时会出现问题。 Python datetime对象不可序列化:

Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 84, in callWithLogger
    return callWithContext({"system": lp}, func, *args, **kw)
  File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 69, in callWithContext
    return context.call({ILogContext: newCtx}, func, *args, **kw)
  File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 118, in callWithContext
    return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 81, in callWithContext
    return func(*args,**kw)
--- <exception caught here> ---
  File "/usr/lib/python2.7/dist-packages/twisted/internet/selectreactor.py", line 146, in _doReadOrWrite
    why = getattr(selectable, method)()
  File "/usr/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 460, in doRead
    rval = self.protocol.dataReceived(data)
  File "./server.py", line 17, in dataReceived
    result = getattr(self.factory, command)(**request)
  File "./server.py", line 35, in execute
    return json.dumps(result)
  File "/usr/lib/python2.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 201, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 264, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python2.7/json/encoder.py", line 178, in default
    raise TypeError(repr(o) + " is not JSON serializable")
exceptions.TypeError: datetime.datetime(2013, 10, 26, 11, 38, 42, 348094) is not JSON serializable

我找到了类似的SO question。但我接受的答案中我不喜欢的是我必须提供自定义序列化器。

在我的缓存中我有不同的命令,但我想对所有缓存命令使用一种JSON格式化方法。如果我要遵循这个答案,我恐怕不得不做一个if-cascade。

有没有办法覆盖datetime.datetime以提供一个将由JSON序列化程序使用的简单方法?或者更好的解决方案呢?

datetime.datetime对我来说,JSON序列化可以像str(d)一样简单(字符串表示)。

1 个答案:

答案 0 :(得分:1)

普遍接受的方法是对默认编码器进行子类化。

import json

class CustomJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if hasattr(obj, 'isoformat'): #handles both date and datetime objects
            return obj.isoformat()
        elif hasattr(obj, 'total_seconds'): #handles both timedelta objects
            return str(obj)
        if isinstance(obj, Decimal): #handles decimal timedelta objects
            return float(obj)
        else:
            return json.JSONEncoder.default(self, obj)

使用新课程:

context['my_json_data'] = json.dumps(my_python_data, cls=CustomJSONEncoder)

问题是没有普遍接受的方式来表示日期,因此Python会强迫您选择。虽然令人沮丧,但Python迫使你接受这样一个事实,即每当你转换你正在做出选择的日期时。