クラスはいつ使うのか
小さな計算は関数で十分です。しかし、商品名と価格、銀行口座の残高と入出金のように、同じデータに対する操作が増えたときはクラスにまとめると関係が明確になります。
クラスにする目安
- 常に一緒に扱う複数の値がある
- その値へ行う操作が複数ある
- 不正な状態にならないようルールを守りたい
すべての辞書をクラスへ変える必要はありません。「役割を説明できるか」を基準にします。
クラスとインスタンス
ProductクラスPYTHON
class Product:
def __init__(self, name: str, price: int):
self.name = name
self.price = price
def total(self, count: int) -> int:
return self.price * count
book = Product("Python入門", 2000)
pen = Product("ペン", 120)
print(book.total(2))
print(pen.name)実行結果OUTPUT
4000
ペンProduct(...) を呼ぶたびに別のインスタンスが作られます。self はメソッドを呼び出したインスタンス自身で、book.total(2) のときはbookを指します。
不正な状態を防ぐ
値を代入する前に検証すると、「価格が負」のような不正なインスタンスが作られるのを防げます。
初期化時に検証PYTHON
class Product:
def __init__(self, name: str, price: int):
if not name.strip():
raise ValueError("商品名は必須です")
if price < 0:
raise ValueError("価格は0以上です")
self.name = name
self.price = pricePythonの先頭アンダースコア(_balanceなど)は「クラス外から直接使わない」という慣習を表します。完全にアクセスを禁止する機能ではないため、利用者とクラスの約束として扱います。
データ中心ならdataclass
主に値を保持するクラスは dataclasses.dataclass で簡潔に書けます。初期化や表示用メソッドが自動生成されます。
座標を表すPYTHON
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
def distance_from_origin(self) -> float:
return (self.x ** 2 + self.y ** 2) ** 0.5
point = Point(3, 4)
print(point)
print(point.distance_from_origin())実行結果OUTPUT
Point(x=3, y=4)
5.0小さなクラスを組み合わせる
継承は「AはBの一種」と言える関係で使います。単に機能を使いたいだけなら、別のオブジェクトを属性として持つ「委譲」のほうが関係を変更しやすくなります。
カートへ商品を持たせるPYTHON
class Cart:
def __init__(self):
self.items: list[Product] = []
def add(self, product: Product) -> None:
self.items.append(product)
def total(self) -> int:
return sum(item.price for item in self.items)まず関数、必要ならクラス 1回しか使わない処理や状態を持たない変換は、無理にクラスへせず関数から始めましょう。
ミニ課題:銀行口座
口座名義と残高を持つ BankAccount クラスを作り、預け入れと引き出しをメソッドにしてください。0以下の金額、残高を超える引き出しは ValueError にします。
確認例 初期残高0、1000円を預ける、400円を引き出す、残高600円になる、700円の引き出しは失敗する、という順番でテストしましょう。
