はじめに
このシリーズでは、Python 初心者にもわかりやすく「便利なデコレータ」の使い方を毎回1つずつ紹介していきます。
💡「そもそもデコレータって何?」という方は、まず以下の記事をご覧ください:
今回は、クラスの中で使えるデコレータのひとつ @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)をクラスレベルで保持
- 集計・統計・ロギング的な処理に便利!
🧩 self
と cls
、それぞれの“便利ポイント”をまとめよう!
種類 | 最初の引数 | アクセスできるもの | 主な用途 | 💡便利なポイント |
---|---|---|---|---|
インスタンスメソッド | self |
インスタンス変数(self.name など) |
個別の状態やふるまいの定義 | インスタンスごとに異なる動作ができる |
クラスメソッド | cls |
クラス変数(cls.school_name など) |
クラス全体に関わる処理・設定管理など | インスタンスなしで使える/継承先でも自動的に対応できる |
✅ まとめ
-
@classmethod
は インスタンスを作らずにクラスにアクセスできる のが最大の強み - 共通設定の変更・継承対応・状態管理など、「クラスというまとまり」を扱う処理に最適
- インスタンスを使わない=シンプルな設計ができる
終わりに
クラスを設計していると「インスタンスには関係ないけど、クラス全体として扱いたい処理」が意外とよく出てきます。そんなときに役立つのが @classmethod
です。
インスタンスを作らずに呼び出せて、共通設定や状態の管理、継承にも柔軟に対応できるのが魅力です!ぜひ意識して@classmethod
を書いてみてください!