Python | 1 日 120 分 × 7 日アプリ学習:クラスで作る商品管理アプリ(中級編)

Web APP Python
スポンサーリンク

3日目のゴール

3日目のテーマは
「クラスで作った商品オブジェクトに対して、更新(Update)と削除(Delete)、検索(Readの応用)を実装すること」 です。

ここまでであなたは、

Product クラスという「商品という型」を作る
Product オブジェクトを複数作り、リストで管理する
商品を登録して一覧表示する

というところまで来ています。

今日はここに、

商品IDで商品を探す
商品情報を更新する
商品を削除する

という「クラス版 CRUD の U と D、そして検索」を乗せていきます。


おさらい Product クラスと products リスト

Product クラスの基本形をもう一度

まずは、土台になる Product クラスを確認します。

class Product:
    def __init__(self, product_id, name, price, stock):
        self.product_id = product_id
        self.name = name
        self.price = price
        self.stock = stock

    def show_info(self):
        print("=== 商品情報 ===")
        print(f"ID: {self.product_id}")
        print(f"名前: {self.name}")
        print(f"価格: {self.price} 円")
        print(f"在庫数: {self.stock}")
Python

ここで大事なのは、__init__
「この商品オブジェクトは、ID・名前・価格・在庫数を持つ」
という“型の前提”を決めていることです。

そして show_info
「この商品自身が、自分の情報を表示する」
という“振る舞い”を表しています。

複数商品を管理する products リスト

2日目では、複数の商品をこう管理していました。

products = []

p1 = Product("p001", "ノートPC", 120000, 5)
p2 = Product("p002", "マウス", 1500, 30)

products.append(p1)
products.append(p2)
Python

この products
「Product オブジェクトが並んだリスト」です。

今日の Update / Delete / 検索は、
この products をどう扱うか、という話になります。


検索の土台 商品IDで1件だけ探す

「どのオブジェクトか」を特定する

更新や削除をする前に、
まずは「対象の商品を見つける」必要があります。

そのための基本になるのが、
「商品IDで1件だけ探す」処理です。

def find_product_by_id(products, product_id):
    for product in products:
        if product.product_id == product_id:
            return product
    return None
Python

ここで深掘りしたいポイントは三つです。

一つ目は、for product in products: で「Product オブジェクトを一つずつ見ている」こと。
二つ目は、product.product_id == product_id で「この商品か?」を判定していること。
三つ目は、見つかったらその場で return product し、見つからなければ None を返していること。

つまり、

「リストの中から、条件に合うオブジェクトを一つ探す」
というパターンを、関数として切り出した形です。

使う側は、こう書けます。

target = find_product_by_id(products, "p002")
if target is None:
    print("そのIDの商品は見つかりませんでした。")
else:
    target.show_info()
Python

ここでのポイントは、
「見つからない可能性があるので、None チェックを必ずする」
という習慣です。


Update 商品情報を更新する

「見つける」→「中身を書き換える」

次に、「商品情報を更新する」処理を作ります。

流れとしては、

商品IDを入力してもらう
そのIDの商品を探す
見つかったら、変更したい項目を聞く
空欄なら変更しない、入力があれば上書きする

という形にします。

def update_product(products):
    print("=== 商品更新 ===")
    product_id = input("更新したい商品ID: ").strip()

    product = find_product_by_id(products, product_id)
    if product is None:
        print("そのIDの商品は存在しません。")
        return

    print("現在の情報:")
    product.show_info()

    new_name = input("新しい商品名(変更しない場合は空欄のまま): ").strip()
    new_price_text = input("新しい価格(変更しない場合は空欄のまま): ").strip()
    new_stock_text = input("新しい在庫数(変更しない場合は空欄のまま): ").strip()

    if new_name != "":
        product.name = new_name

    if new_price_text != "":
        if not new_price_text.isdigit():
            print("価格は数字で入力してください。価格の変更は行いません。")
        else:
            product.price = int(new_price_text)

    if new_stock_text != "":
        if not new_stock_text.isdigit():
            print("在庫数は数字で入力してください。在庫数の変更は行いません。")
        else:
            product.stock = int(new_stock_text)

    print("商品情報を更新しました。")
    product.show_info()
Python

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

最初に find_product_by_id を使って「対象の商品オブジェクト」を特定していること。
product.name = new_name のように、「そのオブジェクトの属性を直接書き換えている」こと。
空欄入力を「変更しない」という意味にしていること。
数字の入力チェックをしてから int() に変換していること。

特に大事なのは、

「Update=オブジェクトの属性を書き換えること」

という感覚です。

辞書のときは user["name"] = ... でしたが、
クラスでは product.name = ... になります。


Delete 商品を削除する

「どの要素か」を特定して、リストから取り除く

削除は、「その商品オブジェクトを products から取り除く」ことです。

ここで少しだけ工夫が必要なのは、
find_product_by_id は「オブジェクト」を返すだけで、
「リストの何番目か」は教えてくれない、という点です。

やり方は二つあります。

一つ目は、「インデックス付きで回す」方法。
二つ目は、「見つけたオブジェクトをそのまま remove する」方法。

ここでは、後者を使います。

def delete_product(products):
    print("=== 商品削除 ===")
    product_id = input("削除したい商品ID: ").strip()

    product = find_product_by_id(products, product_id)
    if product is None:
        print("そのIDの商品は存在しません。")
        return

    print("削除対象の商品:")
    product.show_info()

    confirm = input("本当に削除しますか? (y/N): ").strip().lower()
    if confirm == "y":
        products.remove(product)
        print("商品を削除しました。")
    else:
        print("削除をキャンセルしました。")
Python

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

find_product_by_id で「削除対象のオブジェクト」を特定していること。
products.remove(product) で「そのオブジェクトをリストから取り除いている」こと。
削除前に情報を表示し、確認を挟んでいること。

つまり、

「Delete=リストからそのオブジェクトを取り除く」

という操作になっています。


Read の応用 商品IDで1件だけ表示する

一覧ではなく「ピンポイント表示」

すでに find_product_by_id があるので、
「IDを指定して、その商品だけ表示する」機能は簡単に作れます。

def show_product_detail(products):
    print("=== 商品詳細表示 ===")
    product_id = input("表示したい商品ID: ").strip()

    product = find_product_by_id(products, product_id)
    if product is None:
        print("そのIDの商品は存在しません。")
        return

    product.show_info()
Python

ここでのポイントは、

一覧表示(全件)と、ID指定表示(1件)の違いを意識することです。

一覧表示は「リストを全部回す」。
ID指定表示は「条件に合う1件を探して表示する」。

どちらも「Read(読み取り)」ですが、
やっていることは少し違います。


3日目版メニュー CRUD の形が見えてくる

登録・一覧・更新・削除・詳細表示

ここまで作った機能を、メニューに組み込みます。

def show_menu():
    print("==========")
    print("商品管理アプリ(クラス編 3日目)")
    print("1: 商品を登録する")
    print("2: 商品一覧を表示する")
    print("3: 商品情報を更新する")
    print("4: 商品を削除する")
    print("5: 商品をIDで表示する")
    print("0: 終了")
    print("==========")
Python

main はこうなります。

def main():
    products = []

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

        if choice == "1":
            add_product(products)
        elif choice == "2":
            show_all_products(products)
        elif choice == "3":
            update_product(products)
        elif choice == "4":
            delete_product(products)
        elif choice == "5":
            show_product_detail(products)
        elif choice == "0":
            print("アプリを終了します。")
            break
        else:
            print("不正な入力です。0〜5 のどれかを選んでください。")
Python

これで、

Create(登録)
Read(一覧・詳細表示)
Update(更新)
Delete(削除)

という CRUD の4つが、
クラスとオブジェクトを使って一通りそろいました。


3日目の完成イメージを頭の中でつなげる

「どこで何をしているか」を言葉で説明してみる

ここまでの流れを、コードを見ずに日本語だけで説明するとこうです。

Product クラスは、「商品が持つべき情報(ID・名前・価格・在庫)と、表示の仕方」を定義している。
products は、「Product オブジェクトのリスト」で、商品一覧を表している。

add_product は、「入力された情報から Product を作り、products に追加する(Create)」。
show_all_products は、「products を全部回して、各商品の show_info を呼ぶ(Read)」。
find_product_by_id は、「products の中から、指定IDの Product を探して返す」。
update_product は、「IDで商品を探し、その商品の属性(name, price, stock)を書き換える(Update)」。
delete_product は、「IDで商品を探し、その Product を products から取り除く(Delete)」。
show_product_detail は、「IDで商品を探し、その商品の show_info を呼ぶ(Readの応用)」。

main は、「products を持ちながら、メニューでこれらの機能を呼び分ける“司令塔”」。

ここまで自分の言葉で説明できたら、
クラス版 CRUD の山は、かなりしっかり越えています。


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

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

クラス版 CRUD でも、「やっていることの本質」は辞書版と同じ。
違うのは、「データが辞書かオブジェクトか」「アクセスが []. か」。
Update は「オブジェクトの属性を書き換える」こと。
Delete は「リストからそのオブジェクトを取り除く」こと。
検索は「リストを回して、条件に合うオブジェクトを探す」こと。

4日目以降は、
ここに「価格での並び替え」「在庫が少ない商品だけ表示」など、
クラス版ならではの“気持ちいい書き方”を足していきます。

その土台として、
今日の「クラス+リスト+CRUD」の感覚を、
一度じっくり噛みしめておいてください。

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