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

Web APP Python
スポンサーリンク

1日目のゴール

1日目のテーマは
「class・__init__・オブジェクトを、“商品”という身近な題材で体に入れること」 です。

辞書でユーザーを扱ったときと同じように、
今度は「商品」をクラスで表現していきます。

今日つかみたいのは、この3つです。

クラス=「設計図」
オブジェクト=「設計図から作られた実物」
__init__=「実物が生まれるときに呼ばれる初期化処理」

ここが見えれば、クラスはもう怖くありません。


クラスを「設計図」としてイメージする

辞書との違いを感覚でつかむ

これまでの商品情報を、もし辞書で書くならこうでした。

product = {
    "id": "p001",
    "name": "ノートPC",
    "price": 120000,
    "stock": 5
}
Python

これはこれでアリですが、
「商品に関する処理(値上げ、在庫の増減など)」は
辞書の外側にバラバラに書くことになります。

クラスを使うと、

「商品という“型”を定義する」
「商品に関するデータと処理をひとまとめにできる」

という世界になります。

クラスは、
「こういう情報と振る舞いを持ったものを作りたい、という設計図」
だと思ってください。


最初のクラス Product を作ってみる

class 文で「型の名前」を決める

まずは、超シンプルなクラスから始めます。

class Product:
    pass
Python

これは「Product という名前のクラス(型)を定義しただけ」の状態です。
まだ中身はありません。

ここに、「商品が持つべき情報」を足していきます。


init は「生まれた瞬間に呼ばれるメソッド」

商品が生まれるときに、何を覚えさせるか

クラスから「実物(オブジェクト)」を作るとき、
Python は特別なメソッド __init__ を呼びます。

__init__ は、
「このオブジェクトは、こういう初期状態でスタートします」
と決める場所です。

商品なら、
ID・名前・価格・在庫数を最初に覚えさせたいですよね。

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

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

__init__ の最初の引数は必ず self であること。
self は「今まさに作られている、このオブジェクト自身」を指すこと。
self.product_id = product_id のように書くことで、
「このオブジェクトの中に、product_id という“属性”を作って値を入れている」こと。

つまり、

__init__ の役割は
「オブジェクトが生まれた瞬間に、そのオブジェクトの中に必要な情報をセットする」
ということです。


オブジェクトを実際に作ってみる

クラス名に()をつけると「実物」ができる

さっきの Product クラスを使って、
実際に商品オブジェクトを作ってみます。

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

ここで起きていることを、順番に言葉にするとこうです。

Product("p001", "ノートPC", 120000, 5) を呼ぶ
→ Python が新しい Product オブジェクトを作る
→ そのオブジェクトに対して __init__(self, "p001", "ノートPC", 120000, 5) を呼ぶ
self.product_id などの属性がセットされる
→ 初期化が終わったオブジェクトが p1 に代入される

つまり、
クラス名に () をつけて呼ぶ=そのクラスの“実物(オブジェクト)”を作る
ということです。


オブジェクトの中身を取り出してみる

辞書のキーではなく「ドット」でアクセスする

辞書なら product["name"] でしたが、
オブジェクトではこう書きます。

print(p1.name)        # ノートPC
print(p1.price)       # 120000
print(p2.name)        # マウス
print(p2.stock)       # 30
Python

ここでのポイントは、

p1.name は「p1 というオブジェクトの中の name 属性」
p2.stock は「p2 というオブジェクトの中の stock 属性」

という意味だということです。

辞書のときは「キーでアクセス」でしたが、
オブジェクトでは「ドットで属性にアクセス」します。


商品に「振る舞い」を持たせる

メソッドとして「商品自身の処理」を書く

クラスの強みは、
「データ(属性)」と「処理(メソッド)」を
ひとまとめにできることです。

例えば、「在庫を減らす」処理を考えてみましょう。

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 reduce_stock(self, amount):
        if amount <= 0:
            print("減らす数量は1以上にしてください。")
            return

        if amount > self.stock:
            print(f"在庫が足りません。現在の在庫: {self.stock}")
            return

        self.stock -= amount
        print(f"{self.name} の在庫を {amount} 減らしました。現在の在庫: {self.stock}")
Python

ここで深掘りしたいのは、

reduce_stock の最初の引数も self であること。
self.stock で「この商品オブジェクトの在庫」にアクセスしていること。
self.stock -= amount で「この商品自身の在庫を更新している」こと。

つまり、

「この商品に関する処理は、このクラスのメソッドとして書く」
というスタイルになっています。

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

p1 = Product("p001", "ノートPC", 120000, 5)
p1.reduce_stock(2)   # ノートPC の在庫を 2 減らしました。現在の在庫: 3
p1.reduce_stock(10)  # 在庫が足りません。現在の在庫: 3
Python

「p1 に対して reduce_stock を呼ぶ」
という書き方が、直感的ですよね。


1日目のミニアプリ 商品を1つ登録して表示する

クラスを使った「商品登録+表示」の最小形

今日の締めとして、
「商品を1つ入力してもらい、オブジェクトを作って表示する」
というミニアプリを書いてみます。

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 main():
    print("商品登録アプリ(クラス編 1日目)")

    product_id = input("商品IDを入力してください: ").strip()
    name = input("商品名を入力してください: ").strip()
    price_text = input("価格を入力してください(整数): ").strip()
    stock_text = input("在庫数を入力してください(整数): ").strip()

    if not price_text.isdigit() or not stock_text.isdigit():
        print("価格と在庫数は数字で入力してください。")
        return

    price = int(price_text)
    stock = int(stock_text)

    product = Product(product_id, name, price, stock)

    print("商品を登録しました。")
    product.show_info()


main()
Python

ここでやっていることを、日本語だけで整理するとこうです。

ユーザーから商品ID・名前・価格・在庫数を入力してもらう
価格と在庫数を整数に変換する
その情報を使って Product オブジェクトを1つ作る
そのオブジェクトに show_info を呼んで、情報を表示する

つまり、

「辞書ではなくクラスを使って、商品という“型”を作り、その実物を扱っている」
という状態になっています。


重要ポイントの再確認 self と init とオブジェクト

self は「今このオブジェクト」のこと

クラスの中で出てくる self は、
最初はどうしてもフワッとしがちです。

でも、今日のコードを通して見ると、
こう言い切れます。

self は「今まさに操作している、このオブジェクト自身」。

__init__ の中では
「このオブジェクトにどんな属性を持たせるか」を決めている。

メソッドの中では
「このオブジェクトの属性をどう使うか・どう変えるか」を書いている。

そして、クラス名に () をつけて呼ぶと、
__init__ が呼ばれて「オブジェクト(実物)」が生まれる。

この流れが頭の中でつながっていれば、
クラスの一番大事な山は、もう越えています。


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

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

クラスは「こういう情報と振る舞いを持つものの設計図」。
__init__ は「オブジェクトが生まれるときに、初期状態をセットする場所」。
クラス名に () をつけて呼ぶと、「そのクラスの実物(オブジェクト)」ができる。
オブジェクトの中のデータには obj.name のようにドットでアクセスする。
「商品に関する処理」は、Product クラスのメソッドとして書くとスッキリまとまる。

2日目からは、
この Product をたくさん作って「商品一覧」を管理したり、
クラスをもう1つ作って「商品管理アプリ全体」をクラスで表現したりしていきます。

今日の class__init__・オブジェクトの感覚は、
この先の Python だけじゃなく、
ほとんどすべてのオブジェクト指向言語で一生使う土台になります。

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