Python入門

Pythonのクラスメソッド・インスタンスメソッド・静的メソッドの違いと使い分け【実例4選】

クラスメソッド・インスタンスメソッド・静的メソッドの違い

Pythonでオブジェクト指向プログラミングを学ぶと、インスタンスメソッド・クラスメソッド・静的メソッドの違いで混乱することがあります。

この記事では、Pythonのクラスメソッド・インスタンスメソッド・静的メソッドの違いと使い分けを、実例コードを交えてわかりやすく解説します。「どのメソッドをいつ使えばいいか」の判断基準も整理するので、ぜひ最後まで読んでみてください。

Pythonの3種類のメソッドとは?

Pythonのクラス内で定義できるメソッドには、以下の3種類があります。

  • インスタンスメソッドself を第一引数に取る、最も基本的なメソッド
  • クラスメソッド(@classmethod)cls を第一引数に取り、クラス全体に関わる処理に使う
  • 静的メソッド(@staticmethod)selfcls も不要な、独立した処理をまとめるメソッド

それぞれの違いを一言でまとめると、「何に紐づいた処理なのか」が異なります。順番に見ていきましょう。

インスタンスメソッドとは?(通常のメソッド)

インスタンスメソッドは、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)


静的メソッドは、selfcls も必要としない、クラスにもインスタンスにも依存しない処理をまとめるときに使います。

定義には @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 なし なし(引数で渡されたものだけ) クラスに関連するユーティリティ処理

使い分けの判断フロー

どのメソッドを使うべきか迷ったときは、以下の順番で考えると整理しやすくなります。

  1. self(インスタンスのデータ)を使う?インスタンスメソッド
  2. cls(クラスのデータ)を使う、またはファクトリメソッドを作る?クラスメソッド
  3. どちらも使わないが、クラスにまとめておきたい?静的メソッド

この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入門 第2版 (スッキリわかる入門シリーズ)

もしも

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

初心者に定番のPython入門書

Amazonで見る

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

もしも

徹底攻略! 電子工作&プログラミング Arduinoで学ぶ電子工作完全ガイド

電子工作とプログラミングを同時に学べる

Amazonで見る

実践Claude Code入門―現場で活用するためのAIコーディングの思考法

もしも

実践Claude Code入門―現場で活用するためのAIコーディングの思考法

AIコーディングの現場活用法を学ぶ一冊

Amazonで見る

※本記事にはアフィリエイトリンクが含まれます。

ABOUT ME
やまちゃん
これまで学生と社会人を合わせて5000人以上にプログラミング学習を指導。 ゼロからイチをわかりやすく解説する専門家として活動しており、本業ではArduinoを用いたIoT開発とロボットプログラミングが専門。 Pythonを用いたアプリ開発、ウェブアプリケーションの開発で業務の効率化をサポートしています。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です