Python json.dumps()とは?日本語・整形(indent)・エラーの直し方を実行例で解説
json.dumps()とは、Pythonの辞書やリストをJSON形式の「文字列」に変換する関数です。日本語をそのまま出すならensure_ascii=False、見やすく整形するならindent=2を付けます。
APIに送るデータを作るとき、ログにデータを残すとき、辞書の中身を見やすく表示したいときに使います。この記事のコードはすべてPython 3.12で実行し、その出力を載せています(Python 3.9でも、NaNのエラーメッセージの末尾以外は同じ結果でした。2026年10月18日確認)。仕様は公式ドキュメントのjsonモジュールに基づきます。
json.dumps()とは:辞書をJSON文字列にする
import json
data = {"name": "テックジム", "count": 3, "ok": True}
s = json.dumps(data)
print(s)
print(type(s))
実行結果:
{"name": "\u30c6\u30c3\u30af\u30b8\u30e0", "count": 3, "ok": true}
<class 'str'>
戻り値はstr(文字列)です。見た目は辞書に似ていますが、s["name"]のようには取り出せません。PythonのTrueはJSONのtrueに変わり、文字列はダブルクォートで囲まれます。
名前の末尾のsはstringのsです。ファイルに直接書き込むjson.dump()(sなし)とは別の関数です。
日本語が\u30c6のようになるときはensure_ascii=False
上の結果で「テックジム」が\u30c6\u30c3…になったのは、既定のensure_ascii=TrueがASCII以外の文字をすべてエスケープするためです。データは壊れていないので、読み込めば日本語に戻りますが、人が読むには不便です。
import json
data = {"name": "テックジム"}
print(json.dumps(data))
print(json.dumps(data, ensure_ascii=False))
実行結果:
{"name": "\u30c6\u30c3\u30af\u30b8\u30e0"}
{"name": "テックジム"}
日本語を含むデータをログやファイルに出すなら、ensure_ascii=Falseを付けるのが基本です。
Pythonでjsonを整形して出力する(indent・sort_keys)
「python json 整形」で探している場合の答えは、indentを付けることです。
import json
data = {"name": "テックジム", "tags": ["Python", "AI"]}
print(json.dumps(data, ensure_ascii=False, indent=2))
実行結果:
{
"name": "テックジム",
"tags": [
"Python",
"AI"
]
}
indentには数値(空白の数)のほか、"\t"のような文字列も渡せます。キーを名前順にそろえたいときはsort_keys=Trueを足します。
import json
print(json.dumps({"b": 1, "a": 2}, sort_keys=True))
実行結果:
{"a": 2, "b": 1}
同じ内容なら常に同じ文字列になるので、Gitでの差分確認や、ハッシュ値での比較に向いています。
ファイルをコマンド1行で整形する(ワンライナー)
手元のJSONファイルを整形して見たいだけなら、コードを書かずにコマンドラインで済みます。
$ python3 -m json.tool --no-ensure-ascii --indent 2 in.json
{
"name": "テックジム",
"tags": [
"Python",
"AI"
]
}
Python 3.14からはpython -m jsonでも同じことができ、従来のpython -m json.toolも引き続き使えると公式ドキュメントに書かれています(2026年10月18日確認)。逆に1行に詰めたいときは--compactを付けます。
通信量を減らす:separatorsで空白を消す
import json
data = {"name": "テックジム", "count": 3}
print(json.dumps(data, ensure_ascii=False))
print(json.dumps(data, ensure_ascii=False, separators=(",", ":")))
実行結果:
{"name": "テックジム", "count": 3}
{"name":"テックジム","count":3}
| やりたいこと | 指定する引数 |
|---|---|
| 日本語をそのまま出す | ensure_ascii=False |
| 人が読めるように整形 | indent=2 |
| キーを名前順にそろえる | sort_keys=True |
| 空白を削ってサイズを小さく | separators=(",", ":") |
| datetimeなどを変換する | default=関数 |
| NaNが混ざったらエラーにする | allow_nan=False |
TypeError: Object of type date is not JSON serializable の直し方
import json
import datetime
json.dumps({"d": datetime.date(2026, 10, 18)})
実行結果:
TypeError: Object of type date is not JSON serializable
JSONに対応する型がない値は変換できません。対応表は次のとおりです。
| Python | JSON |
|---|---|
| dict | object |
| list・tuple | array |
| str | string |
| int・float | number |
| True・False | true・false |
| None | null |
| datetime・set・Decimal・bytesなど | そのままでは変換できない |
タプルは配列になるので、読み込むとリストに変わります(json.dumps({"t": (1, 2)})の結果は{"t": [1, 2]})。
defaultで変換方法を渡す
import json
import datetime
data = {"created": datetime.date(2026, 10, 18)}
print(json.dumps(data, default=str))
実行結果:
{"created": "2026-10-18"}
defaultには「変換できない値を受け取り、変換できる値を返す関数」を渡します。型ごとに変えたいときは自分で書きます。
import json
import datetime
from decimal import Decimal
def encoder(o):
if isinstance(o, (datetime.date, datetime.datetime)):
return o.isoformat()
if isinstance(o, Decimal):
return str(o)
if isinstance(o, set):
return sorted(o)
raise TypeError(f"{type(o).__name__} は変換できません")
data = {"d": datetime.date(2026, 10, 18), "price": Decimal("1.10"), "tags": {"b", "a"}}
print(json.dumps(data, ensure_ascii=False, default=encoder))
実行結果:
{"d": "2026-10-18", "price": "1.10", "tags": ["a", "b"]}
Decimalをfloatにすると金額などで誤差が出ることがあるため、この例では文字列にしています。
キーはすべて文字列になる(1とTrueが衝突する)
import json
print(json.dumps({1: "a", 2.5: "b", None: "d"}))
print(json.dumps({1: "a", True: "c"}))
実行結果:
{"1": "a", "2.5": "b", "null": "d"}
{"1": "c"}
JSONのキーは文字列だけなので自動で変換され、読み込んでも数値には戻りません。2行目ではデータが1件消えています。Pythonでは1 == Trueなので、辞書を作った時点で同じキーとして上書きされるためです。
NaNは正しいJSONにならない(allow_nan=False)
import json
print(json.dumps({"x": float("nan")}))
try:
json.dumps({"x": float("nan")}, allow_nan=False)
except ValueError as e:
print("ValueError:", e)
実行結果(Python 3.12):
{"x": NaN}
ValueError: Out of range float values are not JSON compliant: nan
NaNはJSONの仕様にないため、JavaScriptなど他の言語のパーサーは読み込みに失敗します。pandasやNumPyのデータを外部のAPIに渡すときはallow_nan=Falseを付けておくと、混入に気づけます。
json.dumps()とjson.dump()・json.loads()の違い
| 関数 | 向き | 入力 | 出力 |
|---|---|---|---|
json.dumps() |
Python → JSON | 辞書など | 文字列 |
json.dump() |
Python → JSON | 辞書など+ファイル | ファイルに書き込み |
json.loads() |
JSON → Python | 文字列 | 辞書など |
json.load() |
JSON → Python | ファイル | 辞書など |
import json
data = {"name": "テックジム"}
s = json.dumps(data, ensure_ascii=False) # 文字列にする
with open("out.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False) # ファイルに書く
ファイルへ書き込む方法は「Python json.dump()とは?JSONファイルに書き込む方法」、文字列を辞書に戻す方法は「Python json.loads()とは?」で解説しています。
よくある質問
Q. json.dumps()とは何ですか?
Pythonの辞書やリストを、JSON形式の文字列に変換する標準ライブラリの関数です。戻り値はstr型です。
Q. json.dumpsで日本語が文字化けします
文字化けではなく、ASCII以外の文字がエスケープされた状態です。ensure_ascii=Falseを付けると日本語のまま出力されます。
Q. JSONを見やすく整形して出力するには?
json.dumps(data, ensure_ascii=False, indent=2)のようにindentを指定します。ファイルを整形するだけならpython3 -m json.toolも使えます。
Q. json.dumpとjson.dumpsの違いは?
json.dumpsは文字列を返し、json.dumpはファイルオブジェクトに書き込みます。末尾のsはstringのsです。
まとめ
json.dumps()は辞書やリストをJSON文字列に変換する(戻り値はstr)- 日本語は
ensure_ascii=False、整形はindent、順序をそろえるならsort_keys=True - datetime・set・Decimalは
defaultで変換方法を渡す - キーは文字列になり、
1とTrueは衝突する - 外部に渡すデータは
allow_nan=FalseでNaNの混入を防ぐ




