今まで、Python でのクラスメソッド、静的メソッドを意識したことがなかったので、備忘録です。
Difference between staticmethod and classmethod
- 静的メソッドはクラスの外に定義されている関数と同じ。確たる理由がなければわざわざ使う必要はない。
- 特に継承時の動作に違いが出る。
以下のようなファイルをclass_ex.pyとして保存します。
class HelloMethod():
# クラス変数
a = 'class_var'
def __init__(self):
# インスタンス変数
self.b = 'instance_var'
def instance_method_a(self):
return HelloMethod.a
def instance_method_b(self):
return self.b
@classmethod
def class_method_a(cls):
return cls.a
# 当然ながら動かない。
# @classmethod
# def class_method_a(cls):
# return self.b
@staticmethod
def static_method_a():
return HelloMethod.a
class HelloMethodChild(HelloMethod):
a = 'class_var_of_child'
インタラクティブモードを起動して読み込んでおきます。
>>> import class_ex
インスタンスメソッド
インスタンスから呼び出すメソッドです。
当然のことながら、インスタンスを作ってから呼び出します。
また慣習的に仮引数にselfを持ちます。
>>> hello_method = class_ex.HelloMethod() >>> hello_method.instance_method_a() 'class_var' >>> print(hello_method.instance_method_b()) instance_var
クラスメソッド
インスタンスメソッドとは違い、インスタンスを作らずともクラスから呼び出すことのできるメソッドです。
@classmethodをデコレーターにして、慣習的に仮引数にclsを持ちます。
>>> print(class_ex.HelloMethod.class_method_a()) class_var
静的メソッド
クラスメソッドと同じく、インスタンスを作らずとも呼び出すことができるメソッドです。
@staticmethodをデコレーターにします。
>>> print(class_ex.HelloMethod.static_method_a()) class_var
クラスメソッドと静的メソッドの動作の違い
継承をしたときに、クラスメソッドと静的メソッドでは動作の違いが出ます。
# 子クラスのクラス変数を参照する >>> print(class_ex.HelloMethodChild.class_method_a()) class_var_of_child # 親クラスのクラス変数を参照する >>> print(class_ex.HelloMethodChild.static_method_a()) class_var
継承先のクラスから呼び出したときに、クラスメソッドは継承先の子クラスのクラス変数を参照しますが、静的メソッドは継承元の親クラスのクラス変数を参照します。