Python の組み込み関数のデコレーター、クラスメソッド @classmethod の『使用例』と『エラー例』です。
(Python) @classmethod
(クラスメソッド)
(Python) クラス定義(『プログラマのための注釈: クラス定義内で定義された変数はクラス属性であり、全てのインスタンス間で共有されます。』)
(Python) parameter
(パラメーター、仮引数(かりひきすう)、引数)
(Python) class variable
(クラス変数)
クラスを受けとる引数 cls を書く
クラスメソッド classmethod は、クラスを受けとる引数 cls を書くと、動きました。
引数に cls を書かないと、エラーになりました。
class MyClass:
@classmethod
def method():
return '-- classmethod called --'
MyClass.method()
Traceback (most recent call last):
...
TypeError: method() takes 0 positional arguments but 1 was given
引数に cls を書いたら、動きました。
class MyClass:
@classmethod
def method(cls):
return '-- classmethod called --'
MyClass.method()
'-- classmethod called --'
お決まりのインスタンスを作るのに使えた
クラスメソッドは、『お決まりの初期値』を設定したインスタンスを返すメソッドを作るときに、便利でした。
class MyClass:
def __init__(self, value):
self.instance_value = value
return
@classmethod
def method(cls):
return cls(500)
obj = MyClass.method()
obj.instance_value
500
class MyClass:
def __init__(self, value):
self.instance_variable = value
return
@classmethod
def method(cls):
return cls.instance_variable
obj = MyClass(500)
obj.method()
Traceback (most recent call last):
...
AttributeError: type object 'MyClass' has no attribute 'instance_variable'
クラス変数を参照できた
クラスメソッドの中では、クラス名の直下に書いた『クラス変数』が参照できました。
class MyClass:
class_variable = 500
@classmethod
def method(cls):
return cls.class_variable
a = MyClass()
b = MyClass()
MyClass.class_variable
500
a.method()
500
a.class_variable
500
b.method()
500
b.class_variable
500
クラス変数の値を変更したら『作成済みのインスタンス』が影響を受けた
インスタンスを作ったあとに、クラス変数の値を変えたら、既存のインスタンスから参照したクラス変数の値も変わっていました。
すべてのインスタンスから、共通の変数を参照したいときに、便利そうでした。
class MyClass:
class_variable = 500
@classmethod
def method(cls):
return cls.class_variable
a = MyClass()
b = MyClass()
MyClass.class_variable += 111
MyClass.class_variable
611
a.method()
611
a.class_variable
611
b.method()
611
b.class_variable
611