53

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

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

虽然有__str__一种方法可以将已经可用的对象串起来,但似乎有意识地决定不这样做,为什么会这样?

4

4 回答 4

91

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)

正如其他人正确指出的那样,原因是json 的标准没有指定如何表示日期时间。

于 2012-05-23T14:01:05.543 回答
10

你希望它们如何被序列化?

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

于 2012-05-23T13:57:00.117 回答
8

修补 json 模块以使序列化支持日期时间的简单方法。

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()})

导致:'{"created": "2015-08-26T14:21:31.853855"}'

在以下位置查看更多详细信息和一些注意事项: StackOverflow:Python 和 JavaScript 之间的 JSON 日期时间

于 2015-08-26T11:31:37.160 回答
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 数组的函数),而是得到一个警告,这种方法会安静。

于 2016-10-19T21:51:07.393 回答