web-dev-qa-db-ja.com

なぜpythonのdatetimeオブジェクトのJSONシリアル化がdatetimeオブジェクトのボックスから機能しない

Jsonシリアル化がdatetimeオブジェクトに対して機能しないのはなぜですか。私はJSONシリアル化を理解しているので、オブジェクトの基本的な考え方は__str__組み込み関数を使用し、応答として取得したオブジェクトをurlencodeします。しかし、日付時刻の場合、次のエラーが発生します

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

__str__すなわち、すでに利用可能なオブジェクトを文字列化する方法、しかし、それをしないという意識的な決定のように思えます、なぜそうなのでしょうか?

51
dusual

いいえ、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の標準 が日時の表現方法を指定していないからです。

90
Vikas

それらをどのようにシリアル化してほしいですか?

JSONでは日付の処理方法が指定されていないため、python jsonライブラリーはこれらの日付をどのように表現するかを決定できません。 (ブラウザ、スクリプトなど)はJSONの日付も処理します。

10
Martijn Pieters

シリアル化が日時をサポートするように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:JSON datetime between Python and JavaScript

8
davidhadas

実装することなく日時のエンコードとデコードを取得する場合は、 json_tricks を使用できます。これは、さまざまな一般的なタイプのエンコードとデコードを追加するラッパーです。インストールするだけです:

pip install json_tricks

次に、jsonの代わりにjson_tricksからインポートします。例:

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配列の関数など)が、代わりに警告が表示されます。

2
Mark