0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python初心者のための便利なデコレータ解説 #3】クラス全体に使える?@classmethod の使い方と考え方をやさしく解説!

Last updated at Posted at 2025-06-17

はじめに

このシリーズでは、Python 初心者にもわかりやすく「便利なデコレータ」の使い方を毎回1つずつ紹介していきます。

💡「そもそもデコレータって何?」という方は、まず以下の記事をご覧ください:

👉 【Python初心者のための便利なデコレータ解説 #0】そもそもデコレータってなに?仕組みと使い方をやさしく解説!


今回は、クラスの中で使えるデコレータのひとつ @classmethod を紹介します。

このデコレータを使うと、クラス全体に関係する処理を、インスタンスを作らずに呼び出すことができるようになります。

この記事では、@classmethod の使い方やメリットを、具体例を交えながらわかりやすく解説していきます。


Pythonクラスのメソッドと self のまとめ

@classmethod の説明に入る前に、Python のクラスでよく見るキーワード self について先に整理しておきましょう。
これが理解できていないと、@classmethod が難しくなってしまいます。

🔰 self って結局なに?
self「今使ってるそのオブジェクト自身」 を意味する特別なキーワードです。
Python のクラスの中で定義されたメソッド(関数)は、 「どのインスタンス(オブジェクト)の話なのか」 を知る必要があります。そのときに使われるのが self です。

「私の名前はポチです」 というワンちゃんがいたら、
self.name の self は「私(=そのワンちゃん)」のこと。

🐶 具体的な例でイメージしてみよう

例:self を使ったクラス

class Dog:
    def __init__(self, name):
        self.name = name

    def bark(self):
        print(f"{self.name}がワンワン!")


dog = Dog("ポチ")
dog.bark()  # → ポチがワンワン!
  • dog = Dog("ポチ") で、「ポチ」という名前を持つ Dog オブジェクトを作ります
  • dog.bark() を呼ぶとき、Python は自動的に dog 自身を self に渡してくれます

つまり、実際にはこう動いているのと同じです:

Dog.bark(dog)

これを見るとわかるように、dog というインスタンス自身が引数として渡されることで、self の中身が決まります。

つまり、self は「今、誰がこのメソッドを呼んでいるか?」をPythonに伝えるための引数なんです。

だから、このような形でself をメソッドの最初の引数として書いておく必要があるんですね。

def bark(self):
    print(f"{self.name}がワンワン!")

🔁 self.method() って書き方見るけど、それってどういう意味?

例えばこんなクラスがあったとします。

class Dog:
    def __init__(self, name):
        self.name = name

    def introduce(self):
        print(f"ぼくの名前は {self.name} です!")
        self.bark()

    def bark(self):
        print("ワンワン!")


dog = Dog("ポチ")
dog.introduce()

出力

ぼくの名前は ポチ です
ワンワン

このself.dark()は、 「今動いている自分(インスタンス)が持っているメソッド bark を呼び出す」 という意味です。
introduce メソッドの中で「同じインスタンスの他のメソッド」を呼び出しているからです。

self を通じて、自分自身が持っている属性やメソッドにアクセスする、というのがPythonのルールです。

✨ まとめ

  • self は「どのインスタンスが呼び出したか?」を伝えるために必要
  • メソッドの中で self.method() と書くのは、「自分自身の別の機能を使う」ため
  • Pythonでは、インスタンスメソッドを書くときには、最初の引数に self を 明示的に 書くというルール

🤔 self は必ず必要なの? 〜 すべてのメソッドに self がいるわけじゃない!? 〜

ここまで読んだ人は、もしかするとこう思ったかもしれません。

「クラスの中のメソッドって、全部 self 書かなきゃいけないの?」
self を使わないメソッドってアリなの?」
「自分自身の状態を使わないなら、いらないのでは?」

はい!その通りです!
self を使わないメソッドも Python クラスの中で書けますし、それ専用の書き方もちゃんと用意されています。
staticmethodと呼ばれています。詳しく知りたい方は以下の記事を読んでみてください!

👉 Python初心者のための便利なデコレータ解説 #2】 インスタンスなしで関数を呼べる!? @staticmethod の使いどころを解説!

@classmethod とは?

ここからは今回の主役 @classmethod の出番です。

これはその名の通り、 「クラス(class)自身に対して動くメソッド」 を作るためのデコレータです。

self が「オブジェクト自身(インスタンス)」を表していたのに対して、
@classmethod では最初の引数に cls を使うことで、 「クラスそのもの」 にアクセスできます。

たとえばこんなときに役立ちます:

  • インスタンスを作らずに、クラスに関する処理をしたいとき
  • クラス変数(全体で共有される値)にアクセスしたいとき
  • インスタンスの別の作り方(ファクトリメソッド)を提供したいとき

💡 cls は “class” の略。self のクラスバージョンと考えると理解しやすいです。

このあとは、具体的なコード例を見ながら @classmethod がどんなふうに使えるのか、見ていきましょう!

🔧 @classmethod の具体例1:クラス全体の設定を変える

class Student:
    school_name = "サンプル学園"  # クラス変数(全員共通)

    def __init__(self, name):
        self.name = name  # インスタンス変数(個人ごと)

    def introduce(self):
        # self を使ってインスタンスの情報にアクセス
        print(f"私は {self.name} です。{self.school_name} に通っています。")

    @classmethod
    def change_school(cls, new_name):
        # cls を使ってクラス変数を変更
        cls.school_name = new_name

使い方

# インスタンスを2人作る
s1 = Student("アリス")
s2 = Student("ボブ")

s1.introduce()  # → 私は アリス です。サンプル学園 に通っています。
s2.introduce()  # → 私は ボブ です。サンプル学園 に通っています。

# クラスメソッドを使って学校名を変更
Student.change_school("ニューサンプル高校")

s1.introduce()  # → 私は アリス です。ニューサンプル高校 に通っています。
s2.introduce()  # → 私は ボブ です。ニューサンプル高校 に通っています。

✅ ポイント

  • introduce() は個々のインスタンスの状態にアクセス → self を使う
  • change_school() はクラス全体の設定を変更 → cls を使ってクラス変数にアクセスできる
  • インスタンスを作らなくても呼び出せるのが便利!

🔧 @classmethod の具体例2:継承先でも正しく動く汎用メソッド

継承したサブクラスに応じて、クラス変数をうまく使い分けたいときにも @classmethod は便利です。

🧪 例:文字列からインスタンスを作る

class Animal:
    species = "不明"

    @classmethod
    def describe(cls):
        print(f"この動物は {cls.species} です。")

class Cat(Animal):
    species = "ネコ"

class Dog(Animal):
    species = "イヌ"

Cat.describe()  # → この動物は ネコ です。
Dog.describe()  # → この動物は イヌ です。

✅ ポイント

  • cls は呼び出し元のクラスを自動で指すので、サブクラスに応じて動作が変わる

🔧 @classmethod の具体例3:共通の状態を管理する(例:インスタンス生成回数)

インスタンスが何回作られたかなど、クラス全体で管理したい情報にも @classmethod がぴったりです。

class Counter:
    count = 0

    def __init__(self):
        Counter.count += 1

    @classmethod
    def get_count(cls):
        return cls.count
c1 = Counter()
c2 = Counter()

print(Counter.get_count())  # → 2

✅ ポイント

  • 全インスタンス共通の情報(count)をクラスレベルで保持
  • 集計・統計・ロギング的な処理に便利!

🧩 selfcls、それぞれの“便利ポイント”をまとめよう!

種類 最初の引数 アクセスできるもの 主な用途 💡便利なポイント
インスタンスメソッド self インスタンス変数(self.name など) 個別の状態やふるまいの定義 インスタンスごとに異なる動作ができる
クラスメソッド cls クラス変数(cls.school_name など) クラス全体に関わる処理・設定管理など インスタンスなしで使える/継承先でも自動的に対応できる

✅ まとめ

  • @classmethod は インスタンスを作らずにクラスにアクセスできる のが最大の強み
  • 共通設定の変更・継承対応・状態管理など、「クラスというまとまり」を扱う処理に最適
  • インスタンスを使わない=シンプルな設計ができる

終わりに

クラスを設計していると「インスタンスには関係ないけど、クラス全体として扱いたい処理」が意外とよく出てきます。そんなときに役立つのが @classmethod です。
インスタンスを作らずに呼び出せて、共通設定や状態の管理、継承にも柔軟に対応できるのが魅力です!ぜひ意識して@classmethodを書いてみてください!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?