Python | 1 日 120 分 × 7 日アプリ学習:辞書型で作るユーザー管理アプリ(中級編)

Web APP Python
スポンサーリンク

6日目のゴール

6日目のテーマは
「辞書で管理しているユーザー情報を“ファイルに保存・読み込みできるようにすること” です。

ここまでであなたは、メモリ上の users 辞書に対して
CRUD・検索・並び替えを自由にできるようになりました。

でも、プログラムを終了すると、
せっかく登録したユーザー情報は全部消えてしまいます。

6日目ではここに

ユーザー一覧をファイルに保存する
起動時にファイルからユーザー一覧を読み込む
「辞書 ↔ ファイル」の変換の流れを理解する

という「アプリとしての一段上の現実感」を足していきます。


辞書はメモリの中だけの存在という事実

プログラムを止めたら、辞書は消える

これまで扱ってきた users 辞書は、
Python プログラムが動いている間だけ存在します。

プログラムを終了した瞬間、
メモリの中身は消えます。

つまり、
「アプリを閉じてもデータを残したい」なら、
どこかに書き出しておく必要があります。

その「どこか」が、
今日の主役である「ファイル」です。


辞書をそのままファイルに書けるか?

文字列に変換しないと書けない

ファイルに書き込めるのは、基本的に「文字列」です。

users は辞書型なので、
そのまま write(users) のようには書けません。

一度「文字列の形」に変換してから、
ファイルに書き込む必要があります。

ここで出てくるのが
「JSON(ジェイソン)」という形式 です。


JSON という「辞書と相性のいいファイル形式」

Python の dict とほぼ同じ形で保存できる

JSON は、
「辞書やリストをテキストとして表現するためのルール」
だと思ってください。

例えば、こんな users があったとします。

users = {
    "u001": {"id": "u001", "name": "Taro", "age": 25, "email": "taro@example.com"},
    "u002": {"id": "u002", "name": "Hanako", "age": 30, "email": "hanako@example.com"}
}
Python

これを JSON にすると、イメージとしてはこうなります。

{
  "u001": {
    "id": "u001",
    "name": "Taro",
    "age": 25,
    "email": "taro@example.com"
  },
  "u002": {
    "id": "u002",
    "name": "Hanako",
    "age": 30,
    "email": "hanako@example.com"
  }
}

見ての通り、
Python の辞書とかなり似ています。

Python には、この JSON との変換をしてくれる
json モジュールが標準で用意されています。


users 辞書を JSON ファイルに保存する

json.dump で「辞書 → ファイル」を一気にやる

まずは、users をファイルに保存する関数を作ります。

import json


def save_users_to_file(users, filename):
    try:
        with open(filename, "w", encoding="utf-8") as f:
            json.dump(users, f, ensure_ascii=False, indent=2)
        print(f"ユーザー情報をファイルに保存しました: {filename}")
    except OSError as e:
        print("ファイルの保存中にエラーが発生しました。")
        print("詳細:", e)
Python

ここで深掘りしたいポイントは、いくつかあります。

json.dump(users, f, ...) が「辞書を JSON 形式でファイルに書き込む」処理であること。
ensure_ascii=False にすることで、日本語もそのまま読める形で保存されること。
indent=2 によって、見やすい形に整形されること。
tryexcept で「ファイル書き込み時のエラー」をキャッチしていること。

つまり、この関数は
「今の users の状態を、指定したファイルに丸ごとスナップショットとして保存する」
という役割を持っています。


JSON ファイルから users 辞書を読み込む

json.load で「ファイル → 辞書」に戻す

次に、保存したファイルから
users を復元する関数を作ります。

def load_users_from_file(filename):
    try:
        with open(filename, "r", encoding="utf-8") as f:
            users = json.load(f)
        print(f"ユーザー情報をファイルから読み込みました: {filename}")
        return users
    except FileNotFoundError:
        print(f"{filename} が見つかりません。空のユーザー一覧から始めます。")
        return {}
    except json.JSONDecodeError:
        print("ファイルの内容が壊れているか、JSON ではありません。空のユーザー一覧から始めます。")
        return {}
    except OSError as e:
        print("ファイルの読み込み中にエラーが発生しました。空のユーザー一覧から始めます。")
        print("詳細:", e)
        return {}
Python

ここでの重要ポイントは、

ファイルが存在しない場合は、空の {} を返していること。
JSON として読めない場合も、安全のために {} にしていること。
戻り値として users 辞書を返していること。

つまり、

「ファイルがあれば読み込む。なければ空から始める」
という、現実的な挙動になっています。


アプリ起動時に読み込み、終了前に保存する

main の中で「読み込み → 操作 → 保存」の流れを作る

ここまでの関数を、アプリ全体の流れに組み込みます。

DATA_FILE = "users.json"
Python

というファイル名を決めておいて、
main をこう書き換えます。

def main():
    users = load_users_from_file(DATA_FILE)

    while True:
        show_menu()
        choice = input("番号を選んでください: ").strip()

        if choice == "1":
            add_user(users)
        elif choice == "2":
            show_all_users(users)
        elif choice == "3":
            update_user(users)
        elif choice == "4":
            delete_user(users)
        elif choice == "5":
            find_user_by_id(users)
        elif choice == "6":
            find_users_by_name(users)
        elif choice == "7":
            show_users_sorted_by_name(users)
        elif choice == "8":
            show_users_sorted_by_age(users)
        elif choice == "9":
            save_users_to_file(users, DATA_FILE)
        elif choice == "0":
            print("アプリを終了します。変更を保存します。")
            save_users_to_file(users, DATA_FILE)
            break
        else:
            print("不正な入力です。0〜9 のどれかを選んでください。")
Python

ここで深掘りしたいのは、この流れです。

アプリ起動時に load_users_from_file で前回の状態を復元する。
アプリを使っている間は、users 辞書をメモリ上で操作する。
終了時に save_users_to_file で最新状態を保存する。

この構造が見えたら、
「メモリ上の辞書」と「ファイル上の JSON」が、
行き来しているイメージ
がつかめているはずです。


6日目のミニアプリ構成を整理する

データとファイルの関係を日本語で言い切る

ここまでの流れを、あえてコード抜きで言葉だけで整理すると、こうなります。

アプリ起動時
「users.json があれば読み込んで users に入れる。なければ空の users を作る。」

アプリ利用中
「users に対して、登録・更新・削除・検索・並び替えなどを行う。」

アプリ終了時
「今の users の状態を users.json に JSON 形式で書き出す。」

この「起動時に読み込み、終了時に保存する」というパターンは、
ほとんどすべてのデスクトップアプリ・Webアプリで使われている
超基本パターンです。


重要ポイントの深掘り:なぜ JSON を選ぶのか

辞書と相性が良く、人間にも読める

JSON を使うメリットを、改めて整理します。

Python の辞書・リストと形がよく似ているので、変換が簡単。
json.dump / json.load で、ほぼ一行で辞書 ↔ ファイルの変換ができる。
テキスト形式なので、人間が開いて中身を確認できる。

もし、これを自前のフォーマットでやろうとすると、

自分で「書き出し方」と「読み込み方」を両方設計しないといけない
バグが出やすく、メンテナンスも大変

という状態になります。

JSON は、
「辞書やリストをそのまま保存したいときの、ほぼ標準解」
だと思っておいて大丈夫です。


6日目のまとめ:今日つかんでほしい感覚

今日の本質は、これです。

辞書 users はメモリ上のデータであり、プログラム終了とともに消える。
ファイルに残したいときは、「文字列の形」に変換して書き込む必要がある。
JSON は、辞書やリストをテキストとして表現するための便利な形式。
json.dumpjson.load を使えば、「辞書 ↔ ファイル」の変換が簡単にできる。
アプリ起動時に読み込み、終了時に保存することで、「前回の続きから使えるアプリ」になる。

ここまで来たあなたなら、
7日目で「コード全体を自分の言葉で説明する」「機能を少しアレンジする」といった
“中級編の総仕上げ”にも、自然に進んでいけます。

タイトルとURLをコピーしました