概要(JSON は「辞書やリストをそのまま保存・交換できる」テキスト形式)
JSON は、辞書やリストをそのままテキストにしたようなデータ形式です。Python では標準ライブラリの json モジュールで、追加インストールなしに読み書きできます。重要なのは with 文でファイルを開く、encoding を明示(原則 UTF-8)、そして dump/load を使って“正確に”やり取りすることです。
import json
# 書き込み(ファイルへ保存)
data = {"items": ["coffee", "tea"], "qty": 3}
with open("data.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# 読み込み(ファイルから取得)
with open("data.json", "r", encoding="utf-8") as f:
loaded = json.load(f)
Python基本の読み書き(ここが重要)
ファイルへ書く(json.dump)・文字列へ変換(json.dumps)
dump は「ファイルへ」、dumps は「文字列へ」書き出します。日本語をそのまま保存したいなら ensure_ascii=False、見やすくしたいなら indent を付けます。
import json
data = {"名前": "花子", "qty": 2}
# ファイルへ
with open("user.json", "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# 文字列へ
s = json.dumps(data, ensure_ascii=False, indent=2)
print(s)
Pythonファイルから読む(json.load)・文字列から変換(json.loads)
load は「ファイルから」、loads は「文字列から」辞書やリストへ変換します。エンコーディングは必ず UTF-8 を明示しましょう。
import json
# ファイルから
with open("user.json", "r", encoding="utf-8") as f:
user = json.load(f)
# 文字列から
text = '{"name": "coffee", "qty": 2}'
obj = json.loads(text)
Python型対応と整形オプション(重要ポイントの深掘り)
JSON と Python の型の対応関係
- JSON object → Python dict
- JSON array → Python list
- JSON string → Python str
- JSON number → Python int/float
- JSON true/false → Python True/False
- JSON null → Python None
この対応を前提に、数値や真偽値、null の扱いを意識すると混乱が減ります。
表示や差分に強い整形(indent・sort_keys・separators)
- indent: 見やすく整形(例:indent=2)
- sort_keys: キーをソートして書く(差分比較やレビューに便利)
- separators: 余計なスペースを省いてサイズを小さく
import json
data = {"b": 2, "a": 1}
print(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True))
Python日本語の扱い(ensure_ascii=False)
ensure_ascii=True(既定)だと日本語が \uXXXX にエスケープされます。人間が読む前提なら ensure_ascii=False を使いましょう。
json.dumps({"名前": "花子"}, ensure_ascii=False)
Pythonそのまま保存できない型への対応(default・object_hook)
datetime や Decimal など「JSONにない型」はそのまま書けません。default で“文字列化のルール”を定義するか、読み込み時は object_hook で“辞書からの復元”を行います。
import json
from datetime import datetime
def encode_default(obj):
if isinstance(obj, datetime):
return {"__type__": "datetime", "value": obj.isoformat()}
raise TypeError
def decode_object(d):
if d.get("__type__") == "datetime":
return datetime.fromisoformat(d["value"])
return d
payload = {"ts": datetime.now()}
s = json.dumps(payload, default=encode_default, ensure_ascii=False)
obj = json.loads(s, object_hook=decode_object)
Python実務設計と安全策(エンコーディング・Excel 対応・エラー処理)
encoding は原則 UTF-8(必要なら UTF-8-SIG)
日本語を安全に扱うなら UTF-8 が基本。Excel で直接開きたいときは UTF-8-SIG(BOM付き)が有効な場合があります。
import json
with open("excel.json", "w", encoding="utf-8-sig") as f:
json.dump({"名前": "花子"}, f, ensure_ascii=False, indent=2)
Python例外処理(JSONDecodeError)
壊れた JSON を読んだときは例外が出ます。ユーザー向けに分かりやすく扱いましょう。
import json
def read_json_safe(path: str):
try:
with open(path, "r", encoding="utf-8") as f:
return json.load(f)
except FileNotFoundError:
return None
except json.JSONDecodeError as e:
print("JSON の形式が不正です:", e)
return None
Python行ごと JSON(NDJSON)で“追記・大規模”に強くする
巨大データや追記ログは、1行に1オブジェクト(NDJSON)にすると扱いやすくなります。
import json
# 追記
with open("events.ndjson", "a", encoding="utf-8") as f:
f.write(json.dumps({"name": "coffee", "qty": 2}, ensure_ascii=False) + "\n")
# 読み
with open("events.ndjson", "r", encoding="utf-8") as f:
for line in f:
evt = json.loads(line)
Python精度の注意(float の丸め、Decimal 利用)
JSON の number は浮動小数に落ちることがあります。金額などの精度が重要な値は Decimal にパースすると安心です。
import json
from decimal import Decimal
text = '{"price": 1.23}'
obj = json.loads(text, parse_float=Decimal)
Python例題で身につける(定番から一歩先まで)
例題1:設定ファイルの読み書き(整形・日本語)
import json
def save_config(path: str, cfg: dict) -> None:
with open(path, "w", encoding="utf-8") as f:
json.dump(cfg, f, ensure_ascii=False, indent=2, sort_keys=True)
def load_config(path: str) -> dict:
with open(path, "r", encoding="utf-8") as f:
return json.load(f)
cfg = {"サイト名": "コーヒー屋", "theme": "dark", "limit": 50}
save_config("config.json", cfg)
print(load_config("config.json"))
Python例題2:JSON を読みながら型変換・検証
import json
def load_items(path: str) -> list[tuple[str, int]]:
out: list[tuple[str, int]] = []
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
for row in data:
name = row["name"].strip()
qty = int(row["qty"])
out.append((name, qty))
return out
Python例題3:データの差分比較に強い出力
import json
def export_for_diff(path: str, data: dict) -> None:
with open(path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2, sort_keys=True)
Python例題4:NDJSON でログを蓄積し、条件抽出
import json
def append_log(path: str, record: dict) -> None:
with open(path, "a", encoding="utf-8") as f:
f.write(json.dumps(record, ensure_ascii=False) + "\n")
def filter_logs(path: str, min_qty: int) -> list[dict]:
out: list[dict] = []
with open(path, "r", encoding="utf-8") as f:
for line in f:
rec = json.loads(line)
if int(rec.get("qty", 0)) >= min_qty:
out.append(rec)
return out
Pythonまとめ
JSON は「辞書・リストをテキストで安全にやり取り」するための標準形式。Python では json.dump/load(ファイル)、json.dumps/loads(文字列)を使い、UTF-8 を明示、ensure_ascii=False で日本語を保ち、indent/sort_keys で読みやすく。JSON にない型は default/object_hook で変換し、精度が要る数値は Decimal を活用。大規模や追記用途は NDJSON を選べば運用が楽になります。この基本線を押さえるだけで、初心者でも正確・堅牢な JSON 読み書きが短いコードで書けます。
