Pythonのクラスメソッド定義の初歩

クラスメソッドとは?

クラスメソッドはクラス内で定義されたメソッドで、かつインスタンス化しなくても呼び出すことができます。

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

インスタンスメソッドの定義と呼び出し

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

 

[code lang="python"]

class Spam():

def say_spam(self):

return "I'm a spam"

[/code]

 

この例では、say_spamインスタンスメソッドに当たります。

say_spamメソッドは次のように呼び出します。

[code lang="python"]

s = Spam() # ここでSpamクラスをインスタンス

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

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

[/code]

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

[code lang="python"]

print Spam.say_spam()

[/code]

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

 

 

クラスメソッドの定義と呼び出し

クラスメソッドの定義には2通りあります。

(a) classmethod()関数を使う

(b) @classmethodデコレーターを使う

 

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

 

[code lang="python"]

class Eggs():

def say_eggs(self):

return "I'm a Eggs"

say_eggs = classmethod(say_eggs)

[/code]

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

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

[code lang="python"]

print Eggs.say_eggs()

[/code]

このように、Eggsクラスのインスタンス化は不要です。

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

[code lang="python"]

e = Eggs() # Eggsクラスをインスタンス

print e.say_eggs() # エラーが発生します。

[/code]

@classmethodデコレータを使う

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

 

その難点を解消するために@classmethodデコレータがあります。

@classmethodデコレータを使うと、クラスメソッドインスタンスメソッドかどうかがわかりやすくなります。

 

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

 

[code lang="python"]

class Hams():

@classmethod

def say_hams(self):

return "I'm hams"

[/code]

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

 

 

[code lang="python"]

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

h = Hams()

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

[/code]

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