Pythonのjson入門!dump・loadでToDoリストを保存して日本語の文字化けも防ぐ方法
「辞書のデータをファイルに保存したいけど、どう書けばいいの?」
「JSONで保存したら、日本語が さくら みたいな謎の文字になった…」
プログラムで作ったデータを「次に起動したときも使いたい」と思ったら、まず候補になるのが JSON です。Web APIの返事も設定ファイルもJSONが多いので、避けては通れないですよね。
この記事では、Python標準の jsonモジュール を使って、辞書⇔JSONの変換、ファイルへの保存と読み込み、そして初心者がつまずきやすい日本語の文字化けと日時の保存エラーの対処までを、実際に動かしたコードで一緒に見ていきましょう!
対象は、リストと辞書の基本がわかる初心者の方です。インストール不要(標準ライブラリ)なので、すぐに試せますよ😊
JSONとは?Pythonの辞書とそっくりな「データの書き方」

JSON(ジェイソン)は、データを文字で表すための書き方のルールです。イメージとしては、「Pythonの辞書やリストを、ほかのプログラムにも読める形で書き出したもの」です。
見た目はPythonの辞書とほぼ同じですが、細かい違いがあります。変換するときは、次の表のように置き換わります。
| Python | JSON |
|---|---|
| dict(辞書) | object {...} |
| list・tuple | array [...] |
| str | string(必ずダブルクォート ") |
| int・float | number |
| True / False | true / false |
| None | null |
jsonモジュールで覚える関数は、基本の4つだけです。
json.dumps():Pythonのデータ → JSONの文字列json.loads():JSONの文字列 → Pythonのデータjson.dump():Pythonのデータ → JSONファイルに書き込むjson.load():JSONファイルから読み込む → Pythonのデータ
末尾に s が付くほうが「string(文字列)」用、と覚えると迷いません。
dumps・loadsで辞書とJSON文字列を変換する
まずは文字列との変換から試してみます。これ、実行する前に「どんな文字が出るか」予想できますか?
import json
# Pythonの辞書(ふつうのデータ)
user = {
"name": "さくら",
"age": 28,
"skills": ("Python", "Excel"), # タプル
"is_member": True,
"memo": None,
}
# ① 辞書 → JSON文字列(dumps)
text = json.dumps(user)
print(text)
# ② 日本語をそのまま出す+見やすく整形
text = json.dumps(user, ensure_ascii=False, indent=2)
print(text)
# ③ JSON文字列 → 辞書(loads)
data = json.loads(text)
print(type(data), data["skills"], data["is_member"], data["memo"])
実行すると、次のように表示されました。
{"name": "\u3055\u304f\u3089", "age": 28, "skills": ["Python", "Excel"], "is_member": true, "memo": null}
{
"name": "さくら",
"age": 28,
"skills": [
"Python",
"Excel"
],
"is_member": true,
"memo": null
}
<class 'dict'> ['Python', 'Excel'] True None
ここが重要です👇
- 何も指定しないと、日本語は
さくらのようなエスケープ表記になる(壊れてはいませんが、人間には読めません) ensure_ascii=Falseを付けると日本語がそのまま出る。indent=2で改行とインデントが入って読みやすくなる- タプル
("Python", "Excel")は JSON では配列になるので、読み戻すとリスト['Python', 'Excel']になる True→true、None→nullに変わり、loads()で読み戻すと元のTrue・Noneに戻る
冒頭の「謎の文字になった」は、まさにこの ensure_ascii が原因です。日本語を扱うなら ensure_ascii=False はセットで覚えておきましょう。
dump・loadでToDoリストをファイルに保存する
次は、本題のファイル保存です。起動するたびにタスクが1つ増えていく、ミニToDoリストを作ってみます。
ポイントをまとめるとこんな感じです。
- 保存は
json.dump(データ, ファイル)、読み込みはjson.load(ファイル) - ファイルを開くときは
encoding="utf-8"を必ず指定する - 初回はファイルが無いので、
FILE.exists()で確認して空のリストから始める
import json
from pathlib import Path
FILE = Path("todo.json")
def load_todos():
"""保存ファイルを読み込む。初回(ファイルが無い)は空のリストを返す"""
if not FILE.exists():
return []
with FILE.open("r", encoding="utf-8") as f:
return json.load(f)
def save_todos(todos):
"""リストをJSONファイルに保存する"""
with FILE.open("w", encoding="utf-8") as f:
json.dump(todos, f, ensure_ascii=False, indent=2)
todos = load_todos()
print(f"読み込み: {len(todos)}件")
# タスクを1つ追加して保存
todos.append({"title": f"タスク{len(todos) + 1}", "done": False})
save_todos(todos)
for i, todo in enumerate(todos, start=1):
mark = "✅" if todo["done"] else "⬜"
print(f"{i}. {mark} {todo['title']}")

2回続けて実行すると、1回目に保存したタスクが2回目にちゃんと読み込まれました。保存された todo.json の中身はこうなっています。
[
{
"title": "タスク1",
"done": false
},
{
"title": "タスク2",
"done": false
}
]
日本語がそのまま読めて、メモ帳で開いて直接編集することもできます。これがJSONで保存する大きなメリットです🚀
⚠️ encoding を省略しないでください。Windowsでは環境によって、open() の既定の文字コードがUTF-8以外(cp932)になります。書き込みと読み込みで文字コードが食い違うと、UnicodeDecodeError や文字化けの原因になります。encoding="utf-8" を毎回書いておけば、どの環境でも同じように動きます。
つまずきポイント:日時(datetime)はそのまま保存できない
ToDoに「作成日時」を付けたくなったとき、多くの人がここでつまずきます。JSONには日時を表す型が無いので、datetime をそのまま渡すとエラーになるんです。
import json
from datetime import datetime
log = {"event": "ログイン", "at": datetime(2026, 10, 12, 9, 0)}
# ① そのまま変換するとエラーになる
try:
json.dumps(log, ensure_ascii=False)
except TypeError as e:
print("エラー:", e)
# ② 保存するとき:日時を文字列(ISO形式)にしてから変換
saved = json.dumps({**log, "at": log["at"].isoformat()}, ensure_ascii=False)
print("保存:", saved)
# ③ 読み込むとき:文字列を日時に戻す
data = json.loads(saved)
at = datetime.fromisoformat(data["at"])
print("復元:", at, type(at).__name__)

実行結果を見ると、①で Object of type datetime is not JSON serializable(datetime型はJSONに変換できません)というエラーが出ています。
対処のしかたは、つまり「保存するときは文字列に、読むときは日時に戻す」です。
- 保存:
isoformat()で"2026-10-12T09:00:00"のような文字列にする - 読み込み:
datetime.fromisoformat()で datetime 型に戻す
同じように、set(集合)や自作クラスのオブジェクトもそのままでは保存できません。「JSONにできるのは表の型だけ」と覚えておけば、エラーが出ても慌てずに済みますよ。
まとめ
- jsonモジュールは標準ライブラリ。dumps/loads は文字列、dump/load はファイルと変換する
- 日本語を読める形で保存するなら ensure_ascii=False、見やすくするなら indent=2
- ファイルを開くときは encoding=”utf-8″ を必ず指定する
- タプルはリストに、True/None は true/null に変わる
- datetime は isoformat() で文字列にして保存し、fromisoformat() で戻す
設定ファイル・ゲームのセーブデータ・簡単なメモアプリなど、「データを次回も使いたい」場面はたくさんあります。まずはToDoリストのコードを動かして、todo.json の中身をのぞいてみてください。「むずかしそう」が「できそう」に変わるはずです。ぜひ試してみてください😊
\ 読んだら、次は自分で作ってみよう /
筆者が運営する無料の入門コース「作って学ぶPythonプログラミング入門」では、こうした基本文法を、割り勘計算機・おみくじ・数当てゲームなどを作りながら身につけます。各章末の定着ドリル(全42問)で、自分の手で書く練習まで。最初の4レッスンは登録なしで読めます。
こちらも読まれています
📚 関連商品・おすすめ書籍
※本記事にはアフィリエイトリンクが含まれます。




