イントロ
Pythonにおけるクラス変数とインスタンス変数の概念を説明している際、クラス変数として定義したが、インスタンス変数としては定義していない変数に、インスタンス変数の記法であるself.クラス変数名
でアクセスできるのは変ではないか?と気付いた。
→ 簡単なコードを書いてself.クラス変数
の挙動を確認した。
分かったこと
Pythonではself.変数名
と参照すると、
- まずインスタンス変数を参照し、
- インスタンス変数が定義されていない場合には、エラーを返す前に同名のクラス変数を参照する。
混濁を避けるため、インスタンス内でクラス変数を参照する場合はクラス名.クラス変数名
と記載した方が無難。
サンプルコード
self.py
class Hoge:
id = 0
@classmethod
def dump_class(cls):
print("クラス変数: ", cls.id)
def construct(self, id):
self.id = id
def dump_instance(self):
print("インスタンス変数: ", self.id)
if __name__ == "__main__":
Hoge.dump_class() # -> 0
hoge_instance = Hoge()
hoge_instance.dump_instance() # -> 0, インスタンス変数を定義していない場合、同名のクラス変数が参照される
hoge_instance.dump_class() # -> 0
hoge_instance.construct(id=10) # インスタンス変数を定義
hoge_instance.dump_instance() # -> 10, インスタンス変数の参照が優先
hoge_instance.dump_class() # -> 0
参考
クラス変数にアクセスする場合は、特別な理由がない限り「インスタンス.クラス変数」や「self.クラス変数」のようにアクセスすることは避けるべきです。Python ではインスタンス変数をインスタンスオブジェクトから生成することができ、意図せずクラス変数をインスタンス変数で隠蔽してしまうことがあります。
Pythonのクラス変数とインスタンス変数 | UX MILK