4日目のゴール
4日目のテーマは
「クラスで作った商品オブジェクトに“賢さ”を持たせて、並び替えや絞り込みを気持ちよく書けるようになること」 です。
ここまでであなたは、Product クラスを作り、
複数の商品オブジェクトをリストで管理し、
登録・一覧・更新・削除・ID検索までできるようになりました。
今日はそこに、
商品自身に「便利なメソッド」を足す
価格や在庫で絞り込み・並び替えをする
「クラス+オブジェクトだからこそ書けるきれいなコード」を体感する
ここを狙っていきます。
おさらい Product クラスと CRUD の形
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 リストと CRUD の関係
アプリ側では、複数の商品をこう持っていました。
products = []
Pythonここに、Product オブジェクトを追加していきます。
登録は「Product を作って products に追加する」。
一覧は「products をぐるっと回して show_info を呼ぶ」。
更新は「IDで見つけた Product の属性を書き換える」。
削除は「IDで見つけた Product を products から取り除く」。
つまり、
「Product という型」と「products というリスト」が
アプリの土台になっています。
商品に「賢さ」を足す メソッドを増やす
価格に税込み価格を計算するメソッドを足す
クラスの良さは、
「そのデータに関する処理を、そのクラスの中に書ける」ことです。
例えば、「税込み価格」を計算したくなったとします。
辞書でやるなら、外側で
price_with_tax = int(product["price"] * 1.1)
Pythonのように書きますが、
クラスなら「商品自身に計算させる」ことができます。
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}")
def price_with_tax(self, tax_rate=0.1):
return int(self.price * (1 + tax_rate))
Pythonここで深掘りしたいポイントは三つです。
一つ目は、price_with_tax の最初の引数も self であること。
二つ目は、self.price を使って「この商品の価格」を参照していること。
三つ目は、tax_rate にデフォルト値 0.1(10%)を設定していること。
使う側は、こう書けます。
p = Product("p001", "ノートPC", 120000, 5)
print(p.price_with_tax()) # 132000
print(p.price_with_tax(0.08)) # 129600(8%の場合)
Python「p に税込み価格を計算してもらう」という書き方が、
とても自然ですよね。
在庫が少ないかどうかを判定するメソッド
もう一つ、よくあるパターンとして
「在庫が少ない商品だけを知りたい」というニーズがあります。
これも、商品自身に「在庫が少ないかどうか」を判断させると、
コードがきれいになります。
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 is_low_stock(self, threshold=3):
return self.stock <= threshold
Pythonここでのポイントは、
self.stock を使って「この商品の在庫数」を見ていること。threshold にデフォルト値を持たせて、「3個以下なら少ない」とみなしていること。
戻り値が True / False の「判定メソッド」になっていること。
使う側は、こう書けます。
p = Product("p002", "マウス", 1500, 2)
if p.is_low_stock():
print("在庫が少ない商品です。")
Pythonこの「判定ロジックをクラスの中に閉じ込める」感覚は、
この先ずっと使うことになります。
在庫が少ない商品だけを一覧表示する
「オブジェクトのメソッド」を条件に使う
さっきの is_low_stock を使えば、
「在庫が少ない商品だけを表示する」関数は
とてもシンプルに書けます。
def show_low_stock_products(products):
print("=== 在庫が少ない商品一覧 ===")
found = False
for product in products:
if product.is_low_stock():
product.show_info()
print("----------")
found = True
if not found:
print("在庫が少ない商品はありません。")
Pythonここで深掘りしたいのは、この一行です。
if product.is_low_stock():
Pythonこの条件は、
「この product が“在庫が少ない”と自分で判断するなら」
という意味になります。
もし、在庫が少ない基準を「5個以下」に変えたくなったら、is_low_stock の中の threshold を変えるだけで済みます。
アプリ側のコードは一切変えなくていい。
これが「ロジックをクラスに閉じ込める」強さです。
価格で並び替えて表示する
sorted と key をオブジェクトに対して使う
次は、「価格の安い順に商品を並べて表示する」機能を作ります。
辞書のときと同じように、sorted と key を使いますが、
今度は「オブジェクトの属性」を基準にします。
def show_products_sorted_by_price(products):
print("=== 商品一覧(価格の安い順) ===")
if not products:
print("商品がまだ登録されていません。")
return
sorted_products = sorted(products, key=lambda p: p.price)
for product in sorted_products:
product.show_info()
print(f"税込価格: {product.price_with_tax()} 円")
print("----------")
Pythonここでの重要ポイントは三つです。
一つ目は、sorted(products, key=lambda p: p.price) で
「Product オブジェクトの price 属性を基準に並び替えている」こと。
二つ目は、lambda p: p.price が
「並び替えの基準となる値を取り出す小さな関数」になっていること。
三つ目は、並び替えた結果を sorted_products に入れ、
元の products は壊していないこと。
このパターンを覚えると、
「名前順」「在庫数順」なども簡単に書けます。
例えば、在庫の少ない順に並べたいなら、
sorted_products = sorted(products, key=lambda p: p.stock)
Pythonとするだけです。
名前で並び替えるときの注意点
大文字・小文字を気にせず並べたい場合
商品名で並び替えるとき、
「A と a を同じように扱いたい」ことがよくあります。
その場合は、lower() を使って
「小文字にそろえた名前」を基準にします。
def show_products_sorted_by_name(products):
print("=== 商品一覧(名前順) ===")
if not products:
print("商品がまだ登録されていません。")
return
sorted_products = sorted(products, key=lambda p: p.name.lower())
for product in sorted_products:
product.show_info()
print("----------")
Pythonここでのポイントは、
p.name.lower() を key にしていることで、
「大文字・小文字の違いを無視した並び替え」になっていることです。
4日目版メニュー 絞り込みと並び替えを追加する
CRUD に「在庫チェック」と「ソート」を足す
ここまで作った機能を、メニューに組み込みます。
def show_menu():
print("==========")
print("商品管理アプリ(クラス編 4日目)")
print("1: 商品を登録する")
print("2: 商品一覧を表示する")
print("3: 商品情報を更新する")
print("4: 商品を削除する")
print("5: 商品をIDで表示する")
print("6: 在庫が少ない商品を表示する")
print("7: 商品一覧(価格の安い順)")
print("8: 商品一覧(名前順)")
print("0: 終了")
print("==========")
Pythonmain は、こうなります。
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 == "6":
show_low_stock_products(products)
elif choice == "7":
show_products_sorted_by_price(products)
elif choice == "8":
show_products_sorted_by_name(products)
elif choice == "0":
print("アプリを終了します。")
break
else:
print("不正な入力です。0〜8 のどれかを選んでください。")
Pythonこれで、
登録
一覧
更新
削除
ID検索
在庫が少ない商品の絞り込み
価格順・名前順の並び替え
という、かなり“アプリらしい”機能がそろってきます。
「どこを変えれば何が変わるか」を意識する
ロジックはクラスに、操作はアプリ側に
今日のコードを通して、
こんな構造が見えてきたはずです。
在庫が少ない基準を変えたいときは、
Product クラスの is_low_stock を変えればいい。
税込み計算のルールを変えたいときは、
Product クラスの price_with_tax を変えればいい。
並び替えの基準を変えたいときは、sorted(..., key=...) の部分だけを変えればいい。
つまり、
「商品というもののルール」は Product クラスの中に閉じ込める。
「商品をどう並べるか・どう見せるか」はアプリ側の関数で決める。
この役割分担が見えてくると、
コードが一気に整理されて見えます。
4日目のまとめ 今日つかんでほしい感覚
今日の本質は、これです。
クラスは「データ」と「そのデータに関するロジック」を一緒に持てる。__init__ で「このオブジェクトが必ず持つ属性」を決める。
メソッドで「このオブジェクトに関する処理」を表現する。
オブジェクトのメソッドを条件や key に使うと、絞り込みや並び替えがとても書きやすくなる。
「どのロジックをクラスに置き、どのロジックをアプリ側に置くか」を意識すると、設計の感覚が育つ。
5日目以降は、
この商品管理アプリに「ファイル保存」「クラスでアプリ全体を表現する」などを足していきます。
今日の「クラスに賢さを持たせる」感覚は、
オブジェクト指向の世界に一歩踏み込んだ、とても大事な一歩です。


