简体   繁体   English

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

[英]Why does json serialization of datetime objects in python not work out of the box for datetime objects

Why does the json serialization not work for datetime objects . 为什么json序列化不适用于datetime对象。 As I understand json serialization the basic idea for any object can be call the __str__ builtin function and then urlencode the object that you get as a response. 据我了解json序列化,任何对象的基本思想都可以调用__str__ builtin函数,然后将你获得的对象作为响应进行urlencode。 But in case of datetime i get the following error 但是在datetime的情况下,我得到以下错误

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

while there is a __str__ ie a way of stringifying the object already available , But it seems like a conscious decision to not do it , why would that be the case? 虽然有一个__str__即一种对已经可用的对象进行字符串化的方法,但似乎有意识地决定不这样做,为什么会出现这种情况呢?

No it doesn't work that way in json module. 不,它在json模块中不起作用。 The module provides you with a default encoder: json.JSONEncoder . 该模块为您提供了一个默认编码器: json.JSONEncoder You need to extend this to provide your implementation of default method to serialize objects. 您需要扩展它以提供序列化对象的default方法的实现。 Something like this: 像这样的东西:

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)

As others correctly pointed out, the reason is that the standard for json does not specify how date time can be represented. 正如其他人正确指出的那样,原因是json标准没有规定如何表示日期时间。

How would you like them to be serialized? 您希望它们如何序列化?

JSON doesn't specify how to handle dates, so the python json library cannot make the decision on how to then represent these for you. JSON没有指定如何处理日期,因此python json库无法决定如何为您表示这些日期。 That completely depends on how the other side (browser, script, whatever) handles dates in JSON as well. 这完全取决于另一方(浏览器,脚本,等等)如何处理JSON中的日期。

A simple way to patch the json module such that serialization would support datetime. 修补json模块的简单方法,使序列化支持日期时间。

import json
import datetime

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

Than use json serialization as you always do - this time with datetime being serialized as isoformat. 比你经常使用json序列化 - 这次将datetime序列化为isoformat。

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

Resulting in: '{"created": "2015-08-26T14:21:31.853855"}' 导致:'{“created”:“2015-08-26T14:21:31.853855”}'

See more details and some words of caution at: StackOverflow: JSON datetime between Python and JavaScript 请参阅更多详细信息和注意事项: StackOverflow:Python和JavaScript之间的JSON日期时间

If you want to get encoding and decoding of datetimes without having to implement it, you can use json_tricks , which is a wrapper that adds encoding and decoding for various popular types. 如果你想在不必实现它的情况下获得日期时间的编码和解码,你可以使用json_tricks ,它是一个为各种流行类型添加编码和解码的包装器。 Just install: 只需安装:

pip install json_tricks

and then import from json_tricks instead of json , eg: 然后从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)

Disclaimer: it's made by me. 免责声明:它是由我制作的。 Because I had the same problem. 因为我有同样的问题。


If you want to automatically serialize anything that can be stringified, you can do that with just the standard implementation very easily: 如果您想自动序列化任何可以进行字符串化的内容,您可以非常轻松地使用标准实现来实现:

dumps(obj, default=str)

But note that this has disadvantages, eg none of it will be deserialized without extra effort, and maybe sometimes you just don't want to serialize something (like a function of a big numpy array) but get a warning instead, which this method will silence. 但请注意,这有缺点,例如,如果没有额外的努力,它们都不会被反序列化,有时你可能只是不想序列化某些东西(比如一个大的numpy数组的函数)但是会得到一个警告,这个方法将会安静。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM