クラスメソッド
あるメソッドをクラスメソッドにするとき、 Python ではデコレータを使うことができます。
クラスメソッドはクラス内で定義されたメソッドで、かつインスタンス化しなくても呼び出すことができます。
クラス内で定義されるメソッドには、インスタンスメソッドもある。インスタンスメソッドは、インスタンス化されて初めて呼び出すことができます。
インスタンスメソッドが第1引数にインスタンスオブジェクトが渡されるように、クラスメソッドは第1引数にクラスオブジェクトが渡されます。
クラスメソッドの定義と呼び出し
クラスメソッドの定義には2通りあります。
- classmethod()関数を使う
■classmethod(function) ・・・・・・ function のクラスメソッドを返す。 - @classmethodデコレーターを使う
下記のように、インスタンスメソッドは、クラス経由では呼び出す事はできないが、クラスメソッドは、クラス経由、インスタンス経由で呼出すことができます。
class Hoge:
#---インスタンスメソッド。
def sam_ins(self, x): #---第1引数にインスタンスオブジェクトが渡される。
print(x + "instance")
#---デコレータを使ったクラスメソッド。
@classmethod
def sam_cls(cls, x): #---第1引数にクラスオブジェクトが渡される。
print(x + " class")
#---デコレータを使わないクラスメソッド。
def sam_cls(cls, x): #---第1引数にクラスオブジェクトが渡される。
print(x + " class")
sam_cls = classmethod(sam_cls)
#---インスタンスメソッド呼び出し-----------------
i = Hoge()
Hoge.sam_ins("ABC") #---エラーを表示。クラス経由。
i.sam_ins("abc") #---abc instanceを表示。インスタンス経由。
#---クラスメソッド呼び出し-----------------
Hoge.sam_cls("ABC") #---ABC classを表示。クラス経由。
i.sam_cls("abc") #---abc classを表示。インスタンス経由。
クラスメソッドが受け取るクラスオブジェクトについて
クラスメソッドが受け取るクラスオブジェクトは、クラスメソッドが定義されたクラスではなく、クラスメソッドを参照する時に使用されたクラスになります。
class Hoge(object):
@classmethod
def sam_cls(cls, arg):
print('sam_cls')
class Hoge2(Hoge):
pass
上記の場合、
Hoge.sam_cls() とすれば 第1引き数clsには Hogeクラスオブジェクトが、
Hoge2.sam_cls() とすれば第1引き数cls には Hoge2クラスオブジェクトが渡される。
スタティックメソッド
スタティックメソッドでは引数は特に追加されず、インスタンスが無くとも呼び出すことができます。
staticmethod(function)
function の静的メソッドを返す。
静的メソッドは第1引数を受け取らない。
class Hoge(object):
# スタティックメソッド
@staticmethod
def sam_sta(arg):
print(arg + 'sam_sta')
i = Hoge()
i.statmethod("abc") #---abc sam_sta を表示
Hoge.statmethod("ABC") #---ABC sam_sta を表示
スタティックメソッドの存在意義
クラスメソッドとほとんど変わらず、違いと言えば第1引き数にクラスオブジェクトを渡すか、渡さないかの違い。
いろいろと記事を見るとスタティックメソッドの方が処理が早い、メモリ消費が抑えられるなどあるが実際使うとそれほど大したメリットもない。という記事が多かった。
自身の結論ではクラスメソッドで充分ということになった。