Pythonでオブジェクト指向プログラミングを学ぶと、インスタンスメソッド・クラスメソッド・静的メソッドの違いで混乱することがあります。
この記事では、Pythonのクラスメソッド・インスタンスメソッド・静的メソッドの違いと使い分けを、実例コードを交えてわかりやすく解説します。「どのメソッドをいつ使えばいいか」の判断基準も整理するので、ぜひ最後まで読んでみてください。
Pythonの3種類のメソッドとは?
Pythonのクラス内で定義できるメソッドには、以下の3種類があります。
- インスタンスメソッド:
selfを第一引数に取る、最も基本的なメソッド - クラスメソッド(@classmethod):
clsを第一引数に取り、クラス全体に関わる処理に使う - 静的メソッド(@staticmethod):
selfもclsも不要な、独立した処理をまとめるメソッド
それぞれの違いを一言でまとめると、「何に紐づいた処理なのか」が異なります。順番に見ていきましょう。
インスタンスメソッドとは?(通常のメソッド)
インスタンスメソッドは、Pythonクラスで最もよく使われるメソッドです。作成したオブジェクト(インスタンス)ごとに異なる情報(属性)を操作したいときに使います。
クラスの中で定義し、第一引数には必ず self を指定します。この self は「そのインスタンス自身」を指します。
インスタンスメソッドを使う場面
- オブジェクトごとに異なるデータ(属性)にアクセスしたいとき
- インスタンスの状態を変更する処理を行いたいとき
インスタンスメソッドのコード例
class Dog:
def __init__(self, name):
self.name = name
def bark(self): # ← selfがある = インスタンスメソッド
print(f"{self.name}がワンと鳴いた")
dog = Dog("ポチ")
dog.bark() # → ポチがワンと鳴いた
self.name には、インスタンスごとに異なる名前が入ります。Dog("ポチ") なら「ポチ」、Dog("シロ") なら「シロ」です。このようにインスタンス固有のデータを扱う処理がインスタンスメソッドの得意分野です。
クラスメソッドとは?(@classmethod)
クラスメソッドは、クラス全体で共有している情報(クラス変数)にアクセスしたいときや、ファクトリメソッド(別パターンでインスタンスを生成するメソッド)を作りたいときに使います。
定義には @classmethod デコレータを使い、第一引数は cls(クラス自身を指す)にします。
クラスメソッドを使う場面
- クラス変数(全インスタンス共通の値)を参照・更新したいとき
__init__とは別の形でインスタンスを生成するファクトリメソッドを作りたいとき
クラスメソッドのコード例①:クラス変数のカウント
class Dog:
count = 0 # クラス変数(全インスタンスで共有)
def __init__(self, name):
self.name = name
Dog.count += 1
@classmethod
def how_many(cls): # ← clsがある = クラスメソッド
print(f"今までに作られた犬は {cls.count} 匹です")
Dog("ポチ")
Dog("シロ")
Dog.how_many() # → 今までに作られた犬は 2 匹です
クラスメソッドのコード例②:ファクトリメソッド
ファクトリメソッドとは、__init__ とは別の方法でインスタンスを生成するクラスメソッドのことです。たとえば、文字列から犬オブジェクトを生成するケースです。
class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
@classmethod
def from_string(cls, dog_string):
# "ポチ,柴犬" という文字列からインスタンスを生成する
name, breed = dog_string.split(",")
return cls(name, breed)
dog = Dog.from_string("ポチ,柴犬")
print(dog.name) # → ポチ
print(dog.breed) # → 柴犬
このように、データの形式が異なる場合でも柔軟にインスタンスを生成できるのがファクトリメソッドの強みです。
静的メソッドとは?(@staticmethod)
静的メソッドは、self も cls も必要としない、クラスにもインスタンスにも依存しない処理をまとめるときに使います。
定義には @staticmethod デコレータを使います。通常の関数と同じですが、クラスの名前空間に含めることで「このクラスに論理的に関係する処理」であることを明示できます。
静的メソッドを使う場面
- クラスと意味的には関係があるが、インスタンス・クラスのデータを一切使わないとき
ClassName.method()という形で呼び出すことに意味があるとき- ユーティリティ関数をクラス内にまとめて整理したいとき
静的メソッドのコード例
class Dog:
@staticmethod
def is_valid_name(name):
# 名前が1文字以上かつ10文字以下かチェックするユーティリティ
return 1 <= len(name) <= 10
print(Dog.is_valid_name("ポチ")) # → True
print(Dog.is_valid_name("")) # → False
print(Dog.is_valid_name("あいうえおかきくけこさ")) # → False
この is_valid_name はインスタンスの情報もクラス変数も使いませんが、「犬の名前に関するバリデーション」という意味でDogクラスに置くことで、コードの可読性と整理が向上します。
3種類のメソッドの違い【比較表】
Pythonのインスタンスメソッド・クラスメソッド・静的メソッドの違いを一覧表でまとめます。
| 種類 | デコレータ | 第一引数 | アクセスできる情報 | 主な用途 |
|---|---|---|---|---|
| インスタンスメソッド | なし | self |
インスタンス変数・クラス変数 | インスタンス固有のデータ操作 |
| クラスメソッド | @classmethod |
cls |
クラス変数のみ | クラス共通処理・ファクトリメソッド |
| 静的メソッド | @staticmethod |
なし | なし(引数で渡されたものだけ) | クラスに関連するユーティリティ処理 |
使い分けの判断フロー
どのメソッドを使うべきか迷ったときは、以下の順番で考えると整理しやすくなります。
self(インスタンスのデータ)を使う? → インスタンスメソッドcls(クラスのデータ)を使う、またはファクトリメソッドを作る? → クラスメソッド- どちらも使わないが、クラスにまとめておきたい? → 静的メソッド
この3ステップを意識するだけで、Pythonのクラス設計がぐっとシンプルでわかりやすくなります。
実例4選:状況別の使い分けまとめ
最後に、実際のコードでよく登場する使い分けの場面を4つ紹介します。
実例①:ユーザー管理クラスでの使い分け
class User:
user_count = 0 # クラス変数:全ユーザー数
def __init__(self, name, email):
self.name = name
self.email = email
User.user_count += 1
# インスタンスメソッド:インスタンス固有の情報を使う
def greet(self):
print(f"こんにちは、{self.name}さん!")
# クラスメソッド:クラス変数にアクセスする
@classmethod
def get_user_count(cls):
print(f"登録ユーザー数:{cls.user_count}")
# 静的メソッド:メールアドレスのバリデーション(インスタンス・クラス不要)
@staticmethod
def is_valid_email(email):
return "@" in email and "." in email
# 使い方
user1 = User("田中", "tanaka@example.com")
user2 = User("鈴木", "suzuki@example.com")
user1.greet() # → こんにちは、田中さん!
User.get_user_count() # → 登録ユーザー数:2
print(User.is_valid_email("test@a.com")) # → True
実例②:日付クラスのファクトリメソッド(クラスメソッド)
class MyDate:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
# ファクトリメソッド:"2024-06-01" 形式の文字列からインスタンスを生成
@classmethod
def from_iso_string(cls, date_str):
year, month, day = map(int, date_str.split("-"))
return cls(year, month, day)
def show(self):
print(f"{self.year}年{self.month}月{self.day}日")
date = MyDate.from_iso_string("2024-06-01")
date.show() # → 2024年6月1日
実例③:計算ユーティリティをまとめる(静的メソッド)
class MathHelper:
@staticmethod
def add(a, b):
return a + b
@staticmethod
def is_even(n):
return n % 2 == 0
print(MathHelper.add(3, 4)) # → 7
print(MathHelper.is_even(10)) # → True
実例④:継承時のクラスメソッドの挙動(応用)
class Animal:
kind = "動物"
@classmethod
def describe(cls):
print(f"私は {cls.kind} です")
class Dog(Animal):
kind = "犬"
class Cat(Animal):
kind = "猫"
Dog.describe() # → 私は 犬 です
Cat.describe() # → 私は 猫 です
クラスメソッドは継承と組み合わせると、子クラスのクラス変数を自動的に参照してくれます。これは静的メソッドにはない強みです。
まとめ:Pythonのメソッドの使い分けポイント
Pythonのインスタンスメソッド・クラスメソッド・静的メソッドの違いと使い分けを振り返りましょう。
- インスタンスメソッド:
selfを使ってインスタンス固有のデータを操作する → 最も基本的なメソッド - クラスメソッド(@classmethod):
clsを使ってクラス全体の状態を扱う・ファクトリメソッドに使う - 静的メソッド(@staticmethod):インスタンスにもクラスにも依存しない処理をクラスにまとめる
「どのデータを使う処理か?」という視点で考えると、自然と適切なメソッドが選べるようになります。オブジェクト指向設計をさらに深めたい方は、プロパティ(@property)やデコレータの活用についての記事もあわせてご覧ください。
📚 関連記事
- 【Python初心者向け】インスタンスって何?クラス?オブジェクト指向の基礎となるインスタンス化をざっくり解説!— クラス・インスタンスの基礎が必須
- 【Python入門】関数(def文)の使い方を完全解説|引数・return・デフォルト値まで— メソッドの基礎となる関数の理解
- 【初心者向け】超便利!!formatメソッドとf文字列の基本と使い分け— メソッド呼び出しの実践例・使い分け
- 【ざっくり解説】「関数」と「メソッド」の違いって?— 関数とメソッドの違いを明確化





