JSON Formatter Python — json.dumps() ガイド

·Backend Developer·レビュー担当Dmitri Volkov·公開日

無料の JSON整形ツール をブラウザで直接使用 — インストール不要。

JSON整形ツール をオンラインで試す →

Python API クライアントをデバッグしているとき、最初に手が伸びるのは Python pretty print JSON です—— json.dumps(data, indent=4) を1回呼び出すだけで、読みにくい1行の塊が即座にナビゲートしやすい形式になります。 Pythonの組み込み json モジュールは標準ライブラリ内で完全に処理できます——サードパーティのインストールは不要です。 コードを書かずにすばやく結果が欲しい場合は、ToolDeck の JSON フォーマッター が即座に処理します。 このガイドでは、すべての実用的な方法を網羅しています:すべてのパラメータを含む json.dumps()pprint、 高性能フォーマット用の orjsonjson.tool CLI、 APIレスポンスのフォーマットやディスクからの読み込みなど実際のシナリオ—— すべてPython 3.8+対応コードで解説します。 datetime UUID などのカスタム型のシリアライズ、 ijson を使ったギガバイト規模のファイルのストリーミング、rich を使ったターミナルでの構文ハイライトも取り上げます。

まとめ
  • json.dumps(data, indent=4) はPython 2.6からstdlibに組み込まれています——インストール不要。
  • データにアクセント付き文字、日本語、絵文字が含まれる場合は ensure_ascii=False を渡してください。
  • datetimeUUID、カスタムクラスには default= パラメータか json.JSONEncoder のサブクラスを使用してください。
  • separators=(',', ':') はすべての空白を削除します——ネットワーク転送やURLへの埋め込みに使用してください。
  • orjson はstdlibより5–10倍高速で、datetimeuuid.UUID をネイティブに処理します。
  • pprint.pprint() はPython構文(True/None)を出力します、有効なJSONではありません——ファイルやAPIレスポンスには絶対に使用しないでください。
  • 50 MBを超えるJSONファイルは json.load() の代わりに ijson でストリーミングし、MemoryError を防いでください。

JSONの見やすい出力(Pretty Printing)とは?

Pretty printingは、密度の高い最小化されたJSON文字列を、一貫したインデントと 改行を持つ人間が読みやすい形式に変換します。この変換は純粋に見た目の変更です: データは同一で、表示形式だけが変わります。Pythonの json モジュールはこれを標準ライブラリ内で完全に処理します——インストールは不要です。

Before · json
After · json
{"id":"usr_9f3a2b","name":"田中太郎","roles":["admin","editor"],"prefs":{"theme":"dark","lang":"ja"}}
{
    "id": "usr_9f3a2b",
    "name": "田中太郎",
    "roles": [
        "admin",
        "editor"
    ],
    "prefs": {
        "theme": "dark",
        "lang": "ja"
    }
}

json.dumps() — JSONをフォーマットする標準的な方法

json.dumps() はPython 2.6から標準ライブラリの一部です—— import json するだけで、インストール不要です。JSON互換の任意のPythonオブジェクトをフォーマットされた 文字列にシリアライズします。重要なパラメータは indent です:4(または 2)に設定すると 読みやすい出力が得られます。

Python 3.8+ — 最小限の例
import json

user = {
    "id": "usr_9f3a2b",
    "name": "田中太郎",
    "roles": ["admin", "editor"],
    "prefs": {"theme": "dark", "lang": "ja"}
}

print(json.dumps(user, indent=4, ensure_ascii=False))
# 出力:
# {
#     "id": "usr_9f3a2b",
#     "name": "田中太郎",
#     "roles": [
#         "admin",
#         "editor"
#     ],
#     "prefs": {
#         "theme": "dark",
#         "lang": "ja"
#     }
# }

本番環境では多くの場合、 sort_keys=True (実行間で一貫した出力)と ensure_ascii=False (非ASCII文字を読みやすく保持)も必要になります:

Python 3.8+ — sort_keys と ensure_ascii を使用
import json

api_response = {
    "timestamp": "2024-05-01T10:30:00Z",
    "status": "success",
    "data": {
        "user_id": "usr_9f3a2b",
        "display_name": "鈴木花子",
        "city": "東京",
        "score": 4892.5,
        "tags": ["python", "backend", "api"]
    }
}

print(json.dumps(api_response, indent=4, sort_keys=True, ensure_ascii=False))
# 出力(キーがソートされ、日本語文字が保持される):
# {
#     "data": {
#         "city": "東京",
#         "display_name": "鈴木花子",
#         "score": 4892.5,
#         "tags": ["api", "backend", "python"],
#         "user_id": "usr_9f3a2b"
#     },
#     "status": "success",
#     "timestamp": "2024-05-01T10:30:00Z"
# }
注意:json.dumps() は文字列を返します。 フォーマットされたJSONを直接ファイルに書き込むには json.dump(data, f, indent=4) sなし)を使用してください——ファイルオブジェクトに書き込み、 メモリ内の中間文字列の作成を避けられます。

json.dumps() パラメータリファレンス

オブジェクト自体を除いて、すべてのパラメータはオプションです。 デフォルト値はコンパクトでASCIIセーフなJSONを生成します—— 人間が読みやすい出力を得るにはパラメータを明示的に渡してください。

パラメータ
デフォルト
説明
obj
any
JSON形式の文字列にシリアライズするPythonオブジェクト。
indent
int | str | None
None
各インデントレベルのスペース数。None = コンパクトな1行、0 = 改行のみ、4 = 標準。
sort_keys
bool
False
すべてのネストされたレベルで辞書のキーをアルファベット順にソートする。
ensure_ascii
bool
True
非ASCII文字を\uXXXXにエスケープする。Falseに設定するとUnicode文字をそのまま保持する。
separators
tuple | None
None
(item_sep, key_sep) のペア。(",", ":") を使うとスペースなしの最もコンパクトな出力になる。
default
callable | None
None
デフォルトでシリアライズできない型に対して呼び出される。値を拒否するにはTypeErrorを発生させる。
allow_nan
bool
True
float("nan") と float("inf") をJSリテラルとしてシリアライズする。FalseにするとValueErrorが発生する。

separators パラメータでコンパクトなJSON出力を行う

デフォルトでは json.dumps() は項目を ", " で、キーと値を ": " で区切ります。separators パラメータでこれら両方を上書きできます。(',', ':') を渡すとすべての空白が削除され、最もコンパクトな有効JSONが生成されます—— ネットワーク転送、URLへの埋め込み、データベース列へのJSON保存など、 1バイトでも節約したい場合に役立ちます。

Python 3.8+
import json

payload = {
    "endpoint": "/api/v2/events",
    "filters": {"status": "active", "limit": 100},
    "sort": "desc"
}

# デフォルト — 区切り文字後にスペースあり(読みやすい)
default_out = json.dumps(payload)
# {"endpoint": "/api/v2/events", "filters": {"status": "active", "limit": 100}, "sort": "desc"}
# len = 88

# コンパクト — 空白なし
compact_out = json.dumps(payload, separators=(',', ':'))
# {"endpoint":"/api/v2/events","filters":{"status":"active","limit":100},"sort":"desc"}
# len = 80  (9%削減; より大きく深くネストされたpayloadでは節約量が増える)

# コンパクト + ソートされたキー(再現可能なキャッシュキーやコンテンツハッシュ用)
canonical = json.dumps(payload, separators=(',', ':'), sort_keys=True)
print(canonical)
# {"endpoint":"/api/v2/events","filters":{"limit":100,"status":"active"},"sort":"desc"}
注意:indent= separators= を同時に渡す場合、separators 引数はインライン区切り文字のみを制御します——indent による改行とインデントは保持されます。 コンパクトな1行出力が必要な場合は indent を省略 (または None を渡す)し、separators=(',', ':') を設定してください。

default パラメータでカスタムPythonオブジェクトをシリアライズする

標準の json モジュールはdict、list、文字列、数値、真偽値、 None をシリアライズできますが、 その他の型に対しては TypeError を発生させます。 本番コードで最もよく見られる2つは datetime オブジェクトと UUID です。

Python 3.8+ — カスタム処理なしのTypeError
import json
from datetime import datetime, timezone
import uuid

order = {
    "order_id": uuid.uuid4(),            # ❌ TypeError: UUID is not JSON serializable
    "placed_at": datetime.now(timezone.utc),  # ❌ TypeError: datetime is not JSON serializable
    "total_usd": 142.50,
    "items": ["pro-subscription", "addon-storage"]
}

json.dumps(order)  # TypeErrorを発生させる

アプローチ1 — default= パラメータ

default= にcallableを渡します。 json.dumps() は処理できないオブジェクトに対してそれを呼び出します。シリアライズ可能な表現を返すか、 明示的にサポートしない型に対しては TypeError を発生させてください——未知の型を静かに無視しないでください。

Python 3.8+
import json
from datetime import datetime, timezone, date
import uuid
from decimal import Decimal

def json_default(obj):
    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    if isinstance(obj, uuid.UUID):
        return str(obj)
    if isinstance(obj, Decimal):
        return float(obj)
    raise TypeError(f"Type {type(obj).__name__!r} is not JSON serializable")

order = {
    "order_id": uuid.uuid4(),
    "placed_at": datetime(2024, 5, 1, 10, 30, 0, tzinfo=timezone.utc),
    "total_usd": Decimal("142.50"),
    "items": ["pro-subscription", "addon-storage"]
}

print(json.dumps(order, indent=4, default=json_default))
# {
#     "order_id": "a3f1c2d4-e5b6-7890-abcd-ef1234567890",
#     "placed_at": "2024-05-01T10:30:00+00:00",
#     "total_usd": 142.5,
#     "items": ["pro-subscription", "addon-storage"]
# }

アプローチ2 — json.JSONEncoder のサブクラス化

複数のモジュール間で共有される再利用可能なエンコードロジックには、 json.JSONEncoder をサブクラス化する方が、default 関数をあちこちに渡すよりもすっきりします。default メソッドをオーバーライドし、最終フォールバックとして super().default(obj) を呼び出してください——これにより未サポートの型に対する正しいエラー動作が保持されます。

Python 3.8+
import json
from datetime import datetime, timezone
import uuid
from decimal import Decimal

class AppEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        if isinstance(obj, uuid.UUID):
            return str(obj)
        if isinstance(obj, Decimal):
            return float(obj)
        return super().default(obj)  # 未知の型にはTypeErrorを発生させる

order = {
    "order_id": uuid.uuid4(),
    "placed_at": datetime(2024, 5, 1, 10, 30, 0, tzinfo=timezone.utc),
    "total_usd": Decimal("142.50"),
}

# cls= でエンコーダークラスを渡す
print(json.dumps(order, indent=4, cls=AppEncoder))
# default= アプローチと同じ出力
注意:認識されない型には常に super().default(obj)(または明示的に TypeError)を呼び出してください。 すべてに対して str(obj) を静かに返すと、 エラーになるべきオブジェクトが破損します——本番環境では追跡しにくいバグになります。

デコード — object_hook

エンコードは半分にすぎません。JSONからカスタムPythonオブジェクトを再構築するには、json.loads() または json.load() object_hook 関数を渡します。フックはデコードされた各JSONオブジェクト(dict)に対して呼び出され、 代わりに任意のPython値を返せます——完全なエンコード ↔ デコードの往復を実現します。

Python 3.8+
import json
from datetime import datetime
from dataclasses import dataclass

@dataclass
class Event:
    name: str
    occurred_at: datetime
    user_id: str

def encode_event(obj):
    if isinstance(obj, Event):
        return {
            "__type__": "Event",
            "name": obj.name,
            "occurred_at": obj.occurred_at.isoformat(),
            "user_id": obj.user_id,
        }
    raise TypeError(f"Cannot serialize {type(obj)}")

def decode_event(d):
    if d.get("__type__") == "Event":
        return Event(
            name=d["name"],
            occurred_at=datetime.fromisoformat(d["occurred_at"]),
            user_id=d["user_id"],
        )
    return d

# エンコード
event = Event("login", datetime(2024, 5, 1, 10, 30), "usr_9f3a2b")
json_str = json.dumps(event, default=encode_event, indent=4)

# Eventインスタンスにデコードし直す
restored = json.loads(json_str, object_hook=decode_event)
print(type(restored))           # <class 'Event'>
print(restored.occurred_at)     # 2024-05-01 10:30:00
注意:object_hook はドキュメント内のすべてのネストされたdictに対して 呼び出されます——トップレベルだけではありません。カスタムオブジェクトとそのままにしておくべき プレーンなdictを区別できるよう、識別フィールド( "__type__" のような)を含めてください。

pprint — 代替モジュール(と使ってはいけない場面)

Pythonの pprint モジュール(pretty printer)はターミナルでの読みやすさのために Pythonデータ構造をフォーマットします。パースされたPythonオブジェクトに対して動作し、 JSON文字列ではありません——その出力はPythonの構文を使い、JSONの構文ではありません。

Python 3.8+
import json, pprint

raw = '{"sensor_id":"s-441","readings":[23.1,23.4,22.9],"unit":"celsius","active":true}'
data = json.loads(raw)

# pprint — 有効なPython repr、有効なJSONではない
pprint.pprint(data, sort_dicts=False)
# {'sensor_id': 's-441',
#  'readings': [23.1, 23.4, 22.9],
#  'unit': 'celsius',
#  'active': True}        ← Python True、JSON true ではない

# json.dumps — 有効なJSON
print(json.dumps(data, indent=4))
# {
#     "sensor_id": "s-441",
#     "readings": [23.1, 23.4, 22.9],
#     "unit": "celsius",
#     "active": true      ← 有効なJSON
# }
警告:pprint の出力を API エンドポイントに送ったり、.json ファイルに書き込んだりしないでください—— 標準的な構文を期待するJSONパーサーはすべてエラーになります。 有効なJSONである必要があるすべての出力には json.dumps(indent=4) を使用してください。

pprint が適している場面:REPLやデバッグログでのPythonオブジェクトの素早い確認、 特にオブジェクトにJSONシリアライズできない型 (セット、カスタムクラスインスタンス、変換前のdataclass)が含まれている場合。

RequestsのJSONレスポンスをフォーマットする方法

最もよくある実際のシナリオ:ディスク上にJSONファイルがあるか、 APIからHTTPレスポンスがあり、デバッグやロギングのためにフォーマットしたい場合。 どちらも同じアプローチを使います——Pythonのdictにパースしてから json.dumps() でフォーマットします。

ファイルから読み込む

Python 3.8+
import json

try:
    with open("config.json", "r", encoding="utf-8") as f:
        data = json.load(f)

    # コンソールに見やすく出力
    print(json.dumps(data, indent=4, ensure_ascii=False))

    # またはフォーマットされたバージョンをディスクに書き戻す
    with open("config.pretty.json", "w", encoding="utf-8") as f:
        json.dump(data, f, indent=4, ensure_ascii=False)

except json.JSONDecodeError as e:
    print(f"無効なJSON: {e}")
except FileNotFoundError:
    print(f"ファイルが見つかりません: config.json")

APIレスポンスをフォーマットする

Python 3.8+ (必要: pip install requests)
import json, requests
from requests.exceptions import HTTPError, ConnectionError, Timeout

def pretty_print_api(url: str) -> None:
    try:
        resp = requests.get(url, timeout=10)
        resp.raise_for_status()
        print(json.dumps(resp.json(), indent=4, ensure_ascii=False))
    except HTTPError as e:
        print(f"HTTP {e.response.status_code}: {e}")
    except (ConnectionError, Timeout) as e:
        print(f"ネットワークエラー: {e}")
    except json.JSONDecodeError:
        print(f"レスポンスボディがJSONではありません:\n{resp.text[:500]}")

pretty_print_api("https://api.github.com/repos/python/cpython")
注意:response.json() はすでにレスポンスボディをパースしています—— 別途 json.loads() を呼び出す必要はありません。.json() にアクセスする前に必ず raise_for_status() を追加し、 4xx/5xxエラーを混乱を招くパースエラーになる前に捕捉してください。

コマンドラインでのPretty Printing

Pythonには json.tool が付属しています——ターミナルから直接JSONをフォーマットするCLIモジュールで、 Pythonスクリプトは不要です。Pythonがインストールされているどのマシンでも使用できます。

bash
# ローカルファイルをフォーマット
python -m json.tool config.json

# APIレスポンスをフォーマッターにパイプ
curl -s https://api.github.com/users/gvanrossum | python -m json.tool

# 標準入力からフォーマット
echo '{"service":"api-gateway","version":"2.1.0","healthy":true}' | python -m json.tool

# キーをアルファベット順にソート
python -m json.tool --sort-keys data.json

# カスタムインデント(Python 3.9+)
python -m json.tool --indent 2 data.json
注意:Python 3.9で --indent --no-indent フラグが追加されました。 より強力なターミナルJSONフィルタリングには jq を検討してください——ただし python -m json.tool は追加の依存関係なしで フォーマットのユースケースをカバーします。

ターミナルを使っていない場合 — PostmanのレスポンスやログファイルをペーストするときなどはToolDeckの JSON フォーマッター を使えば、シンタックスハイライトとバリデーションを備えた状態でペースト・フォーマット・コピーが一度で完了します。

代替ライブラリ:orjson と rich

orjson — 5–10倍高速でネイティブ型サポートあり

標準の json モジュールはほとんどのユースケースに十分な速度ですが、 毎秒何千ものオブジェクトをシリアライズする場合——ロギングパイプライン、 高スループットAPI、大規模データエクスポート—— orjson は5–10倍高速です。標準ライブラリがカスタム default 関数なしではシリアライズできない型もネイティブに処理します: datetime uuid.UUID、 numpy配列、dataclass。

bash — インストール
pip install orjson
Python 3.8+
import orjson
from datetime import datetime, timezone
import uuid

event = {
    "event_id": uuid.uuid4(),                  # str()不要 — orjsonがUUIDを処理
    "timestamp": datetime.now(timezone.utc),   # isoformat()不要
    "service": "auth-service",
    "level": "INFO",
    "payload": {
        "user_id": "usr_9f3a2b",
        "action": "login",
        "ip": "192.168.1.42",
        "latency_ms": 34
    }
}

# orjson.dumpsはbytesを返す; .decode()でstrに変換
print(orjson.dumps(event, option=orjson.OPT_INDENT_2).decode())
# {
#   "event_id": "a3f1c2d4-e5b6-7890-abcd-ef1234567890",
#   "timestamp": "2024-05-01T10:30:00+00:00",
#   "service": "auth-service",
#   ...
# }

2つの重要な点: orjson.dumps() は文字列ではなく bytes を返します——文字列が必要な場合は .decode() を呼び出してください。 OPT_INDENT_2 による2スペースインデントのみをサポートします; 4スペース出力には標準の json.dumps(indent=4) を使用してください。

rich — ターミナルでの構文ハイライト

ターミナルやREPLでJSONを定期的に確認する場合、 rich は深くネストされた構造を一目で読みやすくする色付きの構文ハイライト出力をレンダリングします。 キー、文字列、数値、真偽値にはそれぞれ異なる色が付きます—— 単色のテキストの壁よりもはるかにスキャンしやすいです。 デバッグ時専用のツールで、本番のシリアライズには使用しません。

bash — インストール
pip install rich
Python 3.8+
from rich import print_json
import json

# print_json() はJSON文字列を受け取る
raw = '{"event":"login","user_id":"usr_9f3a2b","timestamp":"2024-05-01T10:30:00Z","success":true,"meta":{"ip":"192.168.1.42","attempts":1}}'
print_json(raw)

# PythonのdictをPretty Printするには、まず文字列に変換する
data = {
    "status": "success",
    "count": 42,
    "tags": ["python", "api", "backend"]
}
print_json(json.dumps(data))
警告:rich.print_json() はターミナルの色付けのために ANSIエスケープコードを出力します——この出力を .json ファイルに書き込んだり、 APIレスポンスとして送ったりしないでください。 機械で読み取り可能な出力には json.dumps(indent=4) を使用してください。

simplejson — 標準ライブラリの互換性のある代替品

simplejson はPythonの標準 json モジュールになったライブラリです——今でも独立してメンテナンスされており、 マイナーな機能でstdlibより先行しています。真のドロップイン置き換えです: importを変えるだけで残りのコードは変わりません。 カスタムエンコーダーなしで Decimal サポートが必要な場合や、古いPython環境をターゲットにしている場合に役立ちます。

bash — インストール
pip install simplejson
Python 3.8+
import simplejson as json  # stdlibと同じAPI
from decimal import Decimal

order = {
    "item": "API subscription",
    "price": Decimal("49.99"),   # stdlib jsonはここでTypeErrorを発生させる
    "quantity": 3,
}

# simplejsonはDecimalをネイティブにシリアライズ — default=不要
print(json.dumps(order, indent=4, use_decimal=True))
# {
#     "item": "API subscription",
#     "price": 49.99,
#     "quantity": 3
# }
注意:純粋なパフォーマンスには orjson が最良の選択です。 カスタムエンコーダーを書かずにネイティブの Decimal シリアライズが必要な場合、 またはすでにsimplejsonを使っているコードベースのメンテナンス時には simplejson を選んでください。

メモリ不足を避けながら大きなJSONファイルを処理する

json.load() は1つのフィールドにアクセスする前にファイル全体をメモリに読み込みます。 数百万のレコードがあるファイルやギガバイトを超えるペイロードでは、 MemoryError が発生するか、少なくともプロセスがディスクにスワップして極端に遅くなります。

ijson でのストリーミング

ijson はファイルオブジェクトからアイテムを1つずつ生成するストリーミングJSONパーサーです。 完全なデータセットをメモリに保持することなく配列要素を反復できます—— ピークメモリはファイルサイズではなく単一オブジェクトに比例して保たれます。

bash — インストール
pip install ijson
Python 3.8+
import ijson
from decimal import Decimal

# events.json の構造: {"events": [...数百万のオブジェクト...]}
total_revenue = Decimal("0")
login_count = 0

with open("events.json", "rb") as f:   # ijsonはバイナリモードが必要
    for event in ijson.items(f, "events.item"):
        if event.get("type") == "purchase":
            total_revenue += Decimal(str(event["amount_usd"]))
        elif event.get("type") == "login":
            login_count += 1

print(f"Revenue: ${total_revenue:.2f}  |  Logins: {login_count}")
# 2 GBのファイルを~30 MBのピークメモリ使用量で処理
注意:ファイルが約50–100 MBを超えたら json.load() から ijson に切り替えてください。 そのしきい値以下では json.load() の方がシンプルで、 内部でC拡張パーサーを使うため大幅に高速です。 100 MBを超えると、ストリーミングによるメモリの節約が余分なオーバーヘッドを上回ります。

NDJSON — 1行に1つのJSONオブジェクト

NDJSON(改行区切りJSON、JSON Linesや .jsonl とも呼ばれる)は1行に1つの完全なJSONオブジェクトを格納します。 ログエクスポーター、Kafkaコンシューマー、データパイプラインがよくこの形式を生成します—— 各行を独立して追記・読み取りできるため、レコードを追加するためにファイル全体をパースする必要がありません。 追加の依存関係なしで標準ライブラリが処理できます。

Python 3.8+
import json
from pathlib import Path

# NDJSON を書き込む — 1イベントにつき1行
events = [
    {"ts": "2024-05-01T10:00:00Z", "user": "usr_9f3a2b", "action": "login"},
    {"ts": "2024-05-01T10:01:03Z", "user": "usr_9f3a2b", "action": "purchase", "sku": "pro-plan"},
    {"ts": "2024-05-01T10:15:42Z", "user": "usr_4ab1d9", "action": "login"},
]

with open("events.ndjson", "w", encoding="utf-8") as f:
    for event in events:
        f.write(json.dumps(event, ensure_ascii=False) + "\n")

# NDJSON を読み込む — ファイルサイズに関係なく一定のメモリ使用量
purchase_count = 0
with open("events.ndjson", "r", encoding="utf-8") as f:
    for line in f:
        line = line.strip()
        if not line:           # 空行をスキップ
            continue
        event = json.loads(line)
        if event.get("action") == "purchase":
            purchase_count += 1
            print(f"{event['ts']} — {event['user']} bought {event['sku']}")

よくあるミス

これら4つのミスをほぼすべてのコードレビューで見かけます——特に JSON.stringify が自動的にエンコードを処理するJavaScriptから来た開発者に多く見られます。

json.dumps() の代わりに print(data) を使用する

問題: dictに対してprint()を使うとPythonのreprが使われます——出力にはTrue/None(Pythonの構文)が表示され、true/null(JSONの構文)ではありません。有効なJSONではありません。

解決策: 有効で読みやすいJSON出力には常にjson.dumps(data, indent=4)を使用してください。

Before · Python
After · Python
data = {"active": True, "count": None}
print(data)
# {'active': True, 'count': None}
print(json.dumps(data, indent=4))
# {
#     "active": true,
#     "count": null
# }
非ASCII文字を含むテキストでensure_ascii=Falseを忘れる

問題: 特殊文字(日本語、アクセント付き文字、絵文字)が\\uXXXXシーケンスにエスケープされ、出力が読みにくくなります。

解決策: 元のUnicode文字を保持するためにensure_ascii=Falseを渡してください。

Before · Python
After · Python
user = {"name": "田中太郎", "city": "大阪"}
json.dumps(user, indent=2)
# {"name": "\u7530\u4e2d\u592a\u90ce", "city": "\u5927\u962a"}
json.dumps(user, indent=2, ensure_ascii=False)
# {"name": "田中太郎", "city": "大阪"}
ファイルへの書き込みにjson.dumps()を使用する

問題: json.dumps()は文字列を返します;その後別途f.write()の呼び出しが必要になり、不要な中間文字列が作られます。

解決策: json.dump(data, f, indent=4)を使用してください——ファイルオブジェクトに直接書き込みます。

Before · Python
After · Python
with open("out.json", "w") as f:
    f.write(json.dumps(data, indent=4))
with open("out.json", "w", encoding="utf-8") as f:
    json.dump(data, f, indent=4, ensure_ascii=False)
pprintを使って有効なJSONを期待する

問題: pprint.pprint()はPythonの構文(True、None、シングルクォート)を使い、JSONパーサーはこれを拒否します。

解決策: JSONとして解析できる必要があるすべての出力にはjson.dumps(indent=4)を使用してください。

Before · Python
After · Python
import pprint
pprint.pprint({"running": True, "last_error": None})
# {'running': True, 'last_error': None}
import json
print(json.dumps({"running": True, "last_error": None}, indent=4))
# {"running": true, "last_error": null}

メソッド比較 — json.dumps、orjson、simplejson、rich

日常的なフォーマットやファイル書き込みには json.dumps() を使ってください——依存関係ゼロで95%のユースケースをカバーします。 ホットパスでシリアライズする場合や、オブジェクトに datetime UUID フィールドが含まれる場合は orjson を選んでください。stdlib互換で Decimal サポートがすぐに必要な場合は simplejson を使ってください。 rich.print_json() pprint はローカルターミナルの確認のみに厳密に限定してください——どちらも機械で読み取り可能な出力を生成しません。

メソッド
出力
有効なJSON
速度
Non-ASCII
カスタム型
インストール
json.dumps(indent=4)
文字列
標準
ensure_ascii=False
default= / JSONEncoder
組み込み
json.dump(f, indent=4)
ファイル
標準
ensure_ascii=False
default= / JSONEncoder
組み込み
pprint.pprint()
Python repr
標準
ネイティブ
✅ (任意のrepr)
組み込み
orjson.dumps(OPT_INDENT_2)
Bytes
5–10× 高速
ネイティブ
datetime, UUID, numpy
pip install orjson
python -m json.tool
CLI stdout
標準
組み込み
simplejson.dumps()
文字列
~1.5× 高速
ensure_ascii=False
Decimalをネイティブ対応
pip install simplejson
rich.print_json()
ターミナルのみ
✅ (入力)
標準
pip install rich

よくある質問

PythonでJSONを見やすく出力するには?

json.dumps(data, indent=4) を呼び出します。indent パラメータはネストレベルごとのスペース数を設定します。まず json モジュールをインポートしてください——Pythonの標準ライブラリに含まれているため pip install は不要です。データに非ASCII文字(アクセント付き文字や日本語文字)が含まれる場合は ensure_ascii=False を渡してください。

python
import json

user = {"username": "tanaka_taro", "plan": "enterprise", "permissions": ["read", "write", "deploy"]}
print(json.dumps(user, indent=4, ensure_ascii=False))

json.dumps() と json.dump() の違いは何ですか?

json.dumps()("s"あり)はメモリ内のフォーマットされた文字列を返します。json.dump()("s"なし)はファイルライクオブジェクトに直接書き込みます——2番目の引数として開いたファイルハンドルを渡します。ディスクにフォーマットされたJSONを書き込む場合、json.dump(data, f, indent=4) が慣用的で、中間文字列の作成を避けられます。

python
# dumps → メモリ内の文字列
formatted = json.dumps(data, indent=4)

# dump → ファイルに直接書き込む
with open('output.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, indent=4)

json.dumps() が実際の文字の代わりに \u6771\u4eac を表示するのはなぜですか?

デフォルトでは ensure_ascii=True がすべての非ASCII文字を \uXXXX シーケンスにエスケープします。元のUnicode文字を保持するには ensure_ascii=False を設定します。これは名前、住所、非ラテン文字を使用するユーザー生成コンテンツに特に重要です。

python
data = {"city": "東京", "greeting": "こんにちは"}

# デフォルト — エスケープ済み
json.dumps(data, indent=4)
# {"city": "\u6771\u4eac", "greeting": "\u3053\u3093\u306b\u3061\u306f"}

# 読みやすい形式
json.dumps(data, indent=4, ensure_ascii=False)
# {"city": "東京", "greeting": "こんにちは"}

JSON文字列(dictではない)を見やすく出力するには?

まず json.loads() で文字列をパースし、次に json.dumps() でフォーマットします。2つの呼び出しは1行でチェーンでき、ターミナルでの素早い確認に便利です。

python
import json

raw = '{"endpoint":"/api/v2/users","timeout":30,"retry":true}'
print(json.dumps(json.loads(raw), indent=4))

PythonでprintでJSONをフォーマットできますか?

pprint.pprint() はPythonオブジェクトの表現形式を生成するもので、有効なJSONではありません。True/False/None(Pythonの構文)ではなく true/false/null(JSONの構文)を使用します。pprint の出力を API や JSON パーサーに渡さないでください——有効なJSONが必要な場合は json.dumps(indent=4) を使用してください。

python
import pprint, json

data = {"active": True, "score": None}

pprint.pprint(data)     # {'active': True, 'score': None}  ← JSONではない
json.dumps(data, indent=4)  # {"active": true, "score": null}  ← 有効なJSON

PythonでJSONのキーをアルファベット順にソートするには?

json.dumps() に sort_keys=True を追加します。コマンドラインでは python -m json.tool --sort-keys data.json を使います。ソートされたキーにより JSON の差分が読みやすくなり、バージョン間での変更箇所が一目でわかります。

python
import json

server = {"workers": 4, "host": "0.0.0.0", "port": 8080, "debug": False}
print(json.dumps(server, indent=4, sort_keys=True))
# {
#     "debug": false,
#     "host": "0.0.0.0",
#     "port": 8080,
#     "workers": 4
# }

Pythonはカスタムシリアライザー、ストリーミング、パイプライン統合など完全な制御を提供します。フォーマット済みスニペットを確認・共有したいだけのときは、ToolDeckの JSON フォーマッター がより速い方法です:JSONを貼り付けるだけで、環境設定なしにインデント・ハイライトされた結果が得られます。

関連ツール

他の言語でも利用可能:GoJavaScriptBash
MS
Maria SantosBackend Developer

Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.

DV
Dmitri Volkov技術レビュアー

Dmitri is a DevOps engineer who relies on Python as his primary scripting and automation language. He builds internal tooling, CI/CD pipelines, and infrastructure automation scripts that run in production across distributed teams. He writes about the Python standard library, subprocess management, file processing, encoding utilities, and the practical shell-adjacent Python that DevOps engineers use every day.