2017/07/10更新

[Python] dateやdatetimeをjson.dumpでエラーなく出力する

このエントリーをはてなブックマークに追加      

こんにちは、@yoheiMuneです。
Pythonのjsonモジュールを使うといい感じにjsonが扱えますが、dateやdatetimeなどのJSONに定義されていない型は、はうまく文字列に変換できません。今日はその対応Tipsをブログに書きたいと思います。
画像


目次




json.dumpで、dateやdatetimeはエラーになる

こんな感じにエラーになってしまいます。
import json
from datetime import datetime

# datetime型を含むdict
item = { "dt" : datetime.now() }

# JSON文字列にしようとするとエラー
jsonstr = json.dumps(item)

"""
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/Users/munesadayohei/.pyenv/versions/python3.6/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/Users/munesadayohei/.pyenv/versions/python3.6/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/Users/munesadayohei/.pyenv/versions/python3.6/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/Users/munesadayohei/.pyenv/versions/python3.6/json/encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'datetime' is not JSON serializable
"""
これはJSONに日付(date/datetime)の型が定義されていないことが原因で、そのためjsonモジュールはどのように出力すれば良いのかわからず、エラーとなってしまいます。このエラーに対応する方法です。



default指定を利用して、JSON対象外の型もJSON文字列化できるようにする

JSONシリアライズがデフォルトではできないものについて、default引数で変換方法を指定することで、JSON文字列として出力することができます。
import json
from datetime import date, datetime

# date, datetimeの変換関数
def json_serial(obj):
    # 日付型の場合には、文字列に変換します
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    # 上記以外はサポート対象外.
    raise TypeError ("Type %s not serializable" % type(obj))

# datetime型を含むdict
item = { "dt" : datetime.now() }

# default引数を指定して、JSON文字列を生成します
jsonstr = json.dumps(item, default=json_serial)
print(jsonstr) # '{"dt": "2017-07-05T17:01:06.112224"}'
今回はdatetimeやdateの対応方法でしたが、この方法を用いればそれら以外にも対応が可能ですね。



最後に

Pythonは細かいところで今回のようなTipsもありますが、それでもやっぱり色々と便利ですね〜。今後もPythonについて色々とブログを書きたいと思います。

最後になりますが本ブログでは、Python・フロントエンド・Go言語・Linux・Node.js・インフラ・開発関連・Swift・Java・機械学習など雑多に情報発信をしていきます。自分の第2の脳にすべく、情報をブログに貯めています。気になった方は、本ブログのRSSTwitterをフォローして頂けると幸いです ^ ^。

最後までご覧頂きましてありがとうございました!





こんな記事もいかがですか?

RSS画像

もしご興味をお持ち頂けましたら、ぜひRSSへの登録をお願い致します。