Почему сериализация JSON объектов datetime в python не работает из коробки для объектов datetime

почему сериализация json не работает для объектов datetime . Как я понимаю, сериализацию json основной идеей для любого объекта можно назвать __str__ встроенная функция, а затем urlencode объект, который вы получаете в качестве ответа. Но в случае datetime я получаю следующую ошибку

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

хотя есть __str__ i.e способ нанизывания объекта, который уже доступен , но кажется сознательным решением не делать этого, почему это так?

4 ответов


нет, это не работает таким образом в json модуль. Модуль предоставляет вам кодировщик по умолчанию:json.JSONEncoder. Вам нужно расширить это, чтобы обеспечить вашу реализацию default метод сериализации объектов. Что-то вроде этого:--5-->

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 не указывает, как может быть представлено время даты.


Как бы вы хотели, чтобы они были сериализованы?

JSON не указывает, как обрабатывать даты, поэтому python json библиотека не может принять решение о том, как затем представляет эти для вас. Это полностью зависит от того, как другая сторона (браузер, скрипт, что угодно) обрабатывает даты в JSON.


простой способ исправить модуль json таким образом, чтобы сериализация поддерживала datetime.

import json
import datetime

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

чем использовать сериализацию json, как вы всегда делаете - на этот раз с datetime сериализуется как изоформат.

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

в результате: '{"создано": "2015-08-26T14:21: 31.853855"}'

см. больше деталей и некоторые слова предосторежения на: StackOverflow: JSON datetime между Python и JavaScript


если вы хотите получить кодирование и декодирование данных без его реализации, вы можете использовать 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)

отказ от ответственности: это сделано мной. Потому что у меня была такая же проблема.


если вы хотите автоматически сериализовать все, что может быть stringified, вы можете сделать это только со стандартной реализацией очень легко:

dumps(obj, default=str)

но обратите внимание, что это имеет недостатки, например, ни один из них не будет десериализован без дополнительных усилий, и, возможно, иногда вы просто не хотите сериализовать что-то (например, функцию большого массива numpy), но вместо этого получите предупреждение, которое этот метод заставит замолчать.