Dlaczego serializacja JSON obiektów datetime w Pythonie nie działa po wyjęciu z pudełka dla obiektów datetime

Dlaczego serializacja json nie działa dla obiektów datetime . Jak rozumiem serializacja json, podstawową ideą każdego obiektu może być wywołanie wbudowanej funkcji __str__, a następnie kodowanie urlencode obiektu, który otrzymujesz jako odpowiedź. Ale w przypadku datetime dostaję następujący błąd

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

Chociaż istnieje __str__ tj. sposób na przeciągnięcie obiektu już dostępnego, ale wydaje się to świadoma decyzja, aby tego nie robić, dlaczego miałoby tak być?

Author: dusual, 2012-05-23

4 answers

Nie to tak nie działa w module json. Moduł zapewnia domyślny koder: json.JSONEncoder. Należy to rozszerzyć, aby zapewnić implementację metody default do serializacji obiektów. Coś takiego:

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)

Jak słusznie zauważyli inni, powodem jest to, że standard dla json nie określa sposobu reprezentacji czasu daty.

 88
Author: Vikas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-03 09:25:22

Jak chcesz, żeby były serializowane?

JSON nie określa, jak obsługiwać daty, więc biblioteka Pythona json nie może podjąć decyzji, jak je reprezentować. To całkowicie zależy od tego, jak druga strona (przeglądarka, skrypt, cokolwiek) obsługuje daty w JSON, jak również.

 10
Author: Martijn Pieters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-23 13:57:00

Prosty sposób na poprawienie modułu json tak, aby serializacja obsługiwała datetime.

import json
import datetime

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

Niż używać serializacji json jak zawsze - tym razem datetime jest serializowana jako isoformat.

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

W wyniku: "{"utworzono": "2015-08-26T14:21:31.853855"}'

Zobacz więcej szczegółów i kilka słów ostrożności na: StackOverflow: JSON datetime pomiędzy Pythonem a JavaScript

 8
Author: davidhadas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:27

Jeśli chcesz uzyskać kodowanie i dekodowanie danych bez konieczności ich implementacji, możesz użyć json_tricks, który jest opakowaniem, które dodaje kodowanie i dekodowanie dla różnych popularnych typów. Po prostu zainstaluj:

pip install json_tricks

A następnie import z json_tricks zamiast json, np.:

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

Zastrzeżenie: jest zrobione przeze mnie. Bo miałem ten sam problem.


Jeśli chcesz automatycznie serializować wszystko, co można przeciągnąć, możesz to zrobić za pomocą standardowego implementacja bardzo łatwa:

dumps(obj, default=str)

Ale zauważ, że ma to wady, np. żadna z nich nie będzie deserializowana bez dodatkowego wysiłku, a może czasami po prostu nie chcesz serializować czegoś (jak funkcja Wielkiej tablicy numpy), ale zamiast tego otrzymasz ostrzeżenie, które ta metoda uciszy.

 2
Author: Mark,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-19 21:51:07