<Python> staticmethod, classmethod, instancemthod
スタティックメソッド staticmethod
クラスメソッド classmethod
インスタンスメソッド instancemethod
と3種類あるらしい。
何が違って、何がうれしいのか、、、難い、、
これを見つけた。
staticmethod
はなんとなくわかった。
これは単純にファンクションfunction
っぽい。
継承inheritance
した場合、継承先で同じ名前でオーバーライト可能。
classmethod
はこちらにいい例があった。
Life of a Computer Scientist: Really Understanding Python @staticmethod and @classmethod
クラス変数を呼び出す時がミソっぽい。
ちと同じことしてみた。
まずはstaticmethod
で。
In [1]: class aaa(): ...: x = 1 ...: y = 2 ...: @staticmethod ...: def plus(): ...: return x + y ...: In [2]: aaa.plus Out[2]: <function __main__.aaa.plus> In [3]: aaa.plus() --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-3-94dbd059c682> in <module>() ----> 1 aaa.plus() <ipython-input-1-6427408109ac> in plus() 4 @staticmethod 5 def plus(): ----> 6 return x + y 7 NameError: name 'x' is not defined
クラス変数x
にアクセスできず、、、
アクセスするには、次のようにクラスから呼び出す必要あり。
In [4]: class aaa(): ...: x = 1 ...: y = 2 ...: @staticmethod ...: def plus(): ...: return aaa.x + aaa.y ...: In [5]: aaa.plus() Out[5]: 3
で、classmethod
の場合。
特定のクラス名aaa
の代わりに一般名称のcls
を使える。
クラス名aaa
をハードコードhard code
しなくて済む。
In [6]: class aaa(): ...: x = 1 ...: y = 2 ...: @classmethod ...: def plus(cls): ...: return cls.x + cls.y ...: In [7]: aaa.plus() Out[7]: 3
なので継承時が楽。
In [8]: class AAA(aaa): ...: z = 3 ...: @staticmethod ...: def show_z(): ...: return AAA.z ...: In [9]: AAA.plus() Out[9]: 3 In [10]: aaa.plus Out[10]: <bound method aaa.plus of <class '__main__.aaa'>>
なるほど。
ちとわかった気がする。
続き
staticmethod
と classmethod
で継承された時に、
継承先で元のメソッドを呼べるか? やってみた。
まずはclassmethod
In [30]: class bbb(): ...: @classmethod ...: def x(cls): ...: return 'hage' ...: In [31]: class BBB(bbb): ...: @classmethod ...: def x(cls): ...: return 'Turu' ...: In [32]: bbb.x() Out[32]: 'hage' In [33]: BBB.x() Out[33]: 'Turu'
ちゅう感じで継承先で同じ名前のメソッド作ったらオーバーライトされる。
でもsuper()
を使って、、、
In [34]: class BBB(bbb): ...: @classmethod ...: def x(cls): ...: return 'Turu' ...: @classmethod ...: def y(cls): ...: return super(BBB, cls).x ...: In [35]: BBB.y() Out[35]: <bound method bbb.x of <class '__main__.BBB'>>
ということなので、おりゃっと()
をも一回やってみたら、、、
In [40]: BBB.y()() Out[40]: 'hage'
元のメソッドが呼び出せたっぽい。
へー。
staticmethod
の場合は、super()
の引数にcls
を持ってこれないから、
継承元のメソッドは呼び出せないかな、、、たぶん。