为什么python中的日期时间对象的json序列化不能用于日期时间对象的开箱即用

时间:2012-05-23 13:52:03

标签: python json serialization simplejson

为什么json序列化不适用于datetime对象。据我了解json序列化,任何对象的基本思想都可以调用__str__内置函数,然后将你得到的对象作为响应进行urlencode。但是在datetime的情况下我得到以下错误

TypeError: datetime.datetime(2012, 5, 23, 18, 38, 23, 37566) is not JSON serializable

虽然有一种__str__,即一种对已经可用的对象进行字符串化的方法,但似乎有意识地决定不这样做,为什么会出现这种情况呢?

4 个答案:

答案 0 :(得分:89)

不,它在json模块中不起作用。该模块为您提供默认编码器:json.JSONEncoder。您需要扩展它以提供default方法的实现来序列化对象。像这样:

import json
import datetime
from time import mktime

class MyEncoder(json.JSONEncoder):

    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            return int(mktime(obj.timetuple()))

        return json.JSONEncoder.default(self, obj)

print json.dumps(obj, cls=MyEncoder)

正如其他人正确指出的那样,原因是standard for json没有说明日期时间的表示方式。

答案 1 :(得分:10)

您希望如何序列化它们?

JSON没有指定如何处理日期,因此python json库无法决定如何为您表示这些日期。这完全取决于另一方(浏览器,脚本,等等)如何处理JSON中的日期。

答案 2 :(得分:8)

修补json模块的简单方法,使序列化支持datetime。

import json
import datetime

json.JSONEncoder.default = lambda self,obj: (obj.isoformat() if isinstance(obj, datetime.datetime) else None)

比你经常使用json序列化 - 这次将datetime序列化为isoformat。

json.dumps({'created':datetime.datetime.now()})

导致:' {"已创建":" 2015-08-26T14:21:31.853855"}'

在以下位置查看更多详细信息和一些注意事项: StackOverflow: JSON datetime between Python and JavaScript

答案 3 :(得分:2)

如果要在不必实现日期时间的情况下获取日期时间的编码和解码,可以使用json_tricks,这是一个为各种流行类型添加编码和解码的包装器。只需安装:

pip install json_tricks

然后从json_tricks而不是json导入,例如:

from json_tricks import dumps, loads
json = dumps({'name': 'MyName', 'birthday': datetime.datetime(1992, 5, 23, 18, 38, 23, 37566)})
me = loads(json)

免责声明:它是由我制作的。因为我有同样的问题。

如果您想自动序列化可以进行字符串化的任何内容,您可以非常轻松地使用标准实现来实现:

dumps(obj, default=str)

但请注意,这有缺点,例如如果没有额外的努力,它们都不会被反序列化,也许有时你只是不想序列化某些东西(比如一个大的numpy数组的函数),而是得到一个警告,这个方法会沉默。