classメソッドとstaticメソッド
Pythonにはclassメソッドとstaticメソッドがあるけど、Javaなんかに慣れたプログラマーからすると、最初はわかりづらい。具体的にはこんな感じ。
class.py
#!/usr/bin/python class BaseClass: @classmethod def class_method(cls): print("class_method: {0}".format(cls)) @staticmethod def static_method(): print("static_method: {0}".format(BaseClass)) class SubClass(BaseClass): pass BaseClass.class_method() BaseClass.static_method() SubClass.class_method() SubClass.static_method()
$ ./class.py class_method: __main__.BaseClass static_method: __main__.BaseClass class_method: __main__.SubClass static_method: __main__.BaseClass
classメソッド
第一引数でクラスが渡される時点でなんとなくわかるけど、classメソッドは実行時のクラスで実行される。このため、BaseClassで呼ばれれば、BaseClassのメソッド、SubClassで呼ばれれば、SubClassのメソッドとして実行される。
staticメソッド
一方、staticメソッドは実行時のクラスを知る手立てがない(少なくとも僕は知らない)。なので、先ほどのサンプルプログラムではBaseClassを陽に記述している。
この場合はSubClassで呼ばれても、BaseClassのメソッドとして実行される。というより、そもそもどこかのクラスに結びついているという印象が希薄。
インスタンスメソッドから呼び出す。
ちなみに以下のようにすれば、インスタンスメソッドから実行時のクラスで呼び出すこともできる。class2.py
#!/usr/bin/python class BaseClass: def instance_method(self): print("instance_method: {0}".format(self.__class__)) self.class_method() self.static_method() @classmethod def class_method(cls): print("class_method: {0}".format(cls)) @staticmethod def static_method(): print("static_method: {0}".format(BaseClass)) class SubClass(BaseClass): pass b = BaseClass() b.instance_method() b = SubClass() b.instance_method()
$ ./class2.py instance_method: __main__.BaseClass class_method: __main__.BaseClass static_method: __main__.BaseClass instance_method: __main__.SubClass class_method: __main__.SubClass static_method: __main__.BaseClass
使い分け?
classメソッドは、クラスには関係付けたいけど、個々のインスタンスには関係付けない。継承関係で実行時のクラスは表現したい。staticメソッドは、あるクラスと密接な関係があるけど、派生クラスとは関係付けたくない。個々のインスタンスとも関係ない。
...って、とこなのかな。
0 件のコメント:
コメントを投稿