Pythonのクラスメソッド定義の整理

クラスメソッドとは?
クラスメソッドはクラス内で定義されたメソッドで、かつインスタンス化しなくても呼び出すことができます。
クラス内で定義されるメソッドにはもうひとつ、インスタンスメソッドがあります。インスタンスメソッドは、インスタンス化されて初めて呼び出すことが出来ます。


インスタンスメソッドの定義と呼び出し
インスタンスメソッドの定義は特別なことは何もない、普段定義している通りです。

class Spam():
    def say_spam(self):
        return "I'm a spam"

この例では、say_spamインスタンスメソッドに当たります。
say_spamメソッドは次のように呼び出します。

s = Spam()            # ここでSpamクラスをインスタンス化
print s.say_spam()    # インスタンス化したsオブジェクトからsay_spamメソッドを呼び出し

# I'm a Spamと表示される

インスタンスメソッドでは、次のような呼び出しはできません。

print Spam.say_spam()

こういう呼び出しをできるようにするためにはクラスメソッドの定義が必要です。


クラスメソッドの定義と呼び出し
クラスメソッドの定義には2通りあります。
(a) classmethod()関数を使う
(b) @classmethodデコレーターを使う


まずは、classmethod()関数を使う定義から試します。

class Eggs():
    def say_eggs(self):
        return "I'm a Eggs"
    say_eggs = classmethod(say_eggs)

定義した関数をclassmethod()関数で再定義することでクラスメソッドにすることができます。


say_eggs()クラスメソッドは次のように呼び出します。

print Eggs.say_eggs()

このように、Eggsクラスのインスタンス化は不要です。
逆に、Eggsクラスをインスタンス化して呼びだそうとするとエラーが出ます。

e = Eggs()            # Eggsクラスをインスタンス化
print e.say_eggs()    # エラーが発生します。


@classmethodデコレータを使う
classmethod()関数を使ったクラスメソッド化の難点は、クラスメソッドかどうか判断するには、そのメソッドを最後まで読んでみないとわからない、という点です。


その難点を解消するために@classmethodデコレータがあります。
@classmethodデコレータを使うと、クラスメソッドかインスタンスメソッドかどうかがわかりやすくなります。


@classmethodデコレータを使う場合の定義は次のようにクラスメソッドにしたい関数の前に@classmethodと書いて定義します。

class Hams():
    @classmethod
    def say_hams(self):
        return "I'm hams"

このsay_hamsクラスメソッドの呼び出しは、classmethod関数を呼び出す時と全く一緒です。また、インスタンスしたオブジェクトからの呼び出しはエラーに出るのも同じです。

print Hams.say_hams()    # I'm hamsと表示される

h = Hams()
print h.say_hams()       # エラーが発生する


デコレータの仕組みについては別の機会で整理しますが、デコレータの仕組みがわからなくても、クラスメソッドを定義したい時は、classmethod()関数よりも@classmethodデコレータを使うほうが直感的です。