LoginSignup
129
105

More than 3 years have passed since last update.

pythonでjson出力する際に対応していない型(e.g. datetime)の値を変換しながら出力したい

Last updated at Posted at 2014-09-22

pythonでjson出力する際に対応していない型(e.g. datetime)の値を変換しながら出力したい。

対応していない型を含んだ辞書でTypeErrorが発生

pythonでdictをjsonに変換しようとする際にはjson.dumps(json.dump)が使える。
この時、対応していない型の値が含まれていた場合には以下の様な例外が発生する。

# TypeError: datetime.datetime(2000, 1, 1, 0, 0) is not JSON serializable

例えば、datetime objectを含んだ辞書personをjson.dumps仕様とした際には以下のような結果になってしまう。

import json
from datetime import datetime

person = {
    "name": "Foo",
    "age": 20,
    "created_at": datetime(2000, 1, 1)
}

json.dumps(person)
# TypeError: datetime.datetime(2000, 1, 1, 0, 0) is not JSON serializable

default引数に関数を与えることで、対応していない型に対するコールバックを設定する事ができる

json.dumpsは幾つかの引数を取れる。

json.dumps = dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, inden
t=None, separators=None, encoding='utf-8', default=None, sort_keys=False, **kw)
    Serialize ``obj`` to a JSON formatted ``str``.
...

この内のdefault引数に以下のような関数を与えてあげると、対応していない方に対するマッピングを後付で指定することができる。

def support_datetime_default(o):
    if isinstance(o, datetime):
        return o.isoformat()
    raise TypeError(repr(o) + " is not JSON serializable")

今度はjson.dumpsで変換することができる。

person = {
    "name": "Foo",
    "age": 20,
    "created_at": datetime(2000, 1, 1)
}


json.dumps(person, default=support_datetime_default)
# {"created_at": "2000-01-01T00:00:00", "age": 20, "name": "Foo"}

あるいはJSONEncoderを継承したクラスを作成する

json.dumpsにcls引数で変換に利用するクラスを変更できる(defaultではjson.JSONEncoderが使われる)
したがって、以下の様なJSONEncoderを継承したクラスを定義してclsに渡してもOK。

class DateTimeSupportJSONEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, datetime):
            return o.isoformat()
        return super(DateTimeSupportJSONEncoder, self).default(o)

json.dumps(person, cls=DateTimeSupportJSONEncoder)
# {"created_at": "2000-01-01T00:00:00", "age": 20, "name": "Foo"}
129
105
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
129
105