🐍 Python
default引数でdatetime等のカスタム型を変換する
jsonモジュールはdict・list・str・int・float・bool・Noneしか標準では変換できません。datetimeのようなそれ以外の型を含む辞書をdumps()しようとするとTypeErrorになり、default引数で変換方法を教える必要があります。
json.dumps(obj, default=変換関数)
# 変換関数は「標準で変換できないオブジェクト」を受け取り、
# JSON化可能な値(通常は文字列)を返す
import json
from datetime import datetime
dt = datetime(2026, 8, 10, 9, 0, 0)
try:
json.dumps({"created": dt})
except TypeError as e:
print("TypeError:", e)
# TypeError: Object of type datetime is not JSON serializable
# default=strで、変換できない型を文字列化して回避する
import json
from datetime import datetime
dt = datetime(2026, 8, 10, 9, 0, 0)
print(json.dumps({"created": dt}, default=str))
# {"created": "2026-08-10 09:00:00"}
# より厳密な形式にしたい場合は専用の変換関数を渡す
import json
from datetime import datetime
dt = datetime(2026, 8, 10, 9, 0, 0)
print(json.dumps({"created": dt}, default=lambda o: o.isoformat()))
# {"created": "2026-08-10T09:00:00"}
default引数の仕組み
- 呼ばれるタイミング
- 変換対象のオブジェクトが標準対応型でない場合にのみ呼ばれる。標準対応型(dict/list/str/int/float/bool/None)には呼ばれない
- 関数の戻り値
- さらにJSON化できる値(文字列・数値・辞書・リストなど)を返す必要がある。
defaultの戻り値自体が変換不可な型だと、やはりTypeErrorになる
💡 AIコードレビュー観点:default=strは便利だが情報が失われることがある
default=strはどんな型にもとりあえず対応できて便利ですが、オブジェクトの__str__の実装次第で読み込み側が期待する形式と異なる文字列になることがあります。特にdatetimeはstr()だと"2026-08-10 09:00:00"(空白区切り)になり、ISO 8601形式("T"区切り)を期待する他システムとの連携では書式が合わない可能性があります。相手システムの期待する形式に合わせて、defaultにはできるだけ専用の変換関数を渡すことをおすすめします。