Pythonのクラス内で定義できるメソッドには、主に3つの種類があります。これらは、「データ(変数)へのアクセス権」や「呼び出し方」に違いがあり、役割に応じて適切に使い分ける必要があります。
- インスタンスメソッド: 個々のオブジェクト(インスタンス)のデータを操作する。
- クラスメソッド: クラス全体のデータ(クラス変数)を操作する。
- スタティックメソッド: クラスやインスタンスの状態に依存しない、独立した処理を行う。
この記事では、商品管理クラスを例にして、これら3つのメソッドの定義方法と具体的な使い分けについて解説します。
1. インスタンスメソッド (Instance Method)
最も一般的で基本的なメソッドです。メソッドの第一引数に必ず self を受け取ります。self を通じて、インスタンスごとのデータ(インスタンス変数)にアクセスしたり、変更したりする場合に使用します。
定義と使用例
class Product:
# クラス変数(全商品共通の消費税率)
tax_rate = 0.1
def __init__(self, name, price):
self.name = name
self.price = price
# --- インスタンスメソッド ---
def show_detail(self):
"""
個々の商品の詳細を表示する
self.name や self.price にアクセスできる
"""
total_price = int(self.price * (1 + Product.tax_rate))
print(f"商品名: {self.name} | 税抜: {self.price}円 | 税込: {total_price}円")
# インスタンス化
item1 = Product("Laptop", 100000)
item2 = Product("Mouse", 2000)
# インスタンスからメソッドを呼び出す
item1.show_detail()
item2.show_detail()
実行結果:
商品名: Laptop | 税抜: 100000円 | 税込: 110000円
商品名: Mouse | 税抜: 2000円 | 税込: 2200円
show_detail は、item1 や item2 といった特定のインスタンスの情報を表示するために self を利用しています。
2. クラスメソッド (Class Method)
クラス全体に関わる処理を行うメソッドです。定義の直前に @classmethod デコレータを付け、第一引数に cls(クラス自身)を受け取ります。
主に「クラス変数の変更」や、インスタンス生成の代替手段(ファクトリーメソッド)として利用されます。
定義と使用例
class Product:
tax_rate = 0.1
def __init__(self, name, price):
self.name = name
self.price = price
# --- クラスメソッド ---
@classmethod
def change_tax_rate(cls, new_rate):
"""
全商品共通の消費税率を変更する
cls.tax_rate でクラス変数にアクセスする
"""
print(f"消費税率を {cls.tax_rate} から {new_rate} に変更します。")
cls.tax_rate = new_rate
# 現在の税率で計算
item = Product("Keyboard", 5000)
print(f"変更前の税率: {Product.tax_rate}")
# クラスメソッドを呼び出して税率を変更(クラス名から呼び出すのが一般的)
Product.change_tax_rate(0.15)
print(f"変更後の税率: {Product.tax_rate}")
実行結果:
変更前の税率: 0.1
消費税率を 0.1 から 0.15 に変更します。
変更後の税率: 0.15
change_tax_rate は特定の商品の価格には関心がなく、クラス全体の設定である tax_rate を操作するために cls を利用しています。
3. スタティックメソッド (Static Method)
クラスの中に定義されていますが、インスタンス(self)にもクラス(cls)にも依存しないメソッドです。定義の直前に @staticmethod デコレータを付けます。第一引数に self や cls を取りません。
クラスのデータを使わない「ユーティリティ的な処理(計算やチェックなど)」を、関連性の高いクラス内にまとめておきたい場合に使用します。
定義と使用例
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
# --- スタティックメソッド ---
@staticmethod
def is_valid_price(price):
"""
価格が正当かどうか(0以上か)をチェックする
self も cls も使わず、引数 price だけで判定する
"""
return price >= 0
# メソッドの利用
price_check1 = Product.is_valid_price(5000)
price_check2 = Product.is_valid_price(-100)
print(f"5000円は有効?: {price_check1}")
print(f"-100円は有効?: {price_check2}")
実行結果:
5000円は有効?: True
-100円は有効?: False
is_valid_price は、単なる数値の判定ロジックであり、Product クラスの状態や特定のインスタンスの情報は必要としません。しかし、「商品価格のチェック」という文脈上、このクラスに属している方が自然であるため、スタティックメソッドとして定義されています。
まとめ
| 種類 | デコレータ | 第一引数 | 用途 |
| インスタンスメソッド | なし | self | インスタンスごとのデータ操作 |
| クラスメソッド | @classmethod | cls | クラス変数の操作、ファクトリーメソッド |
| スタティックメソッド | @staticmethod | なし | クラスの状態に依存しない独立した処理 |
これらを適切に使い分けることで、クラスの役割が明確になり、読みやすく保守性の高いコードになります。
