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