4
3

More than 1 year has passed since last update.

Pythonにおける「self.クラス変数」でのクラス変数・インスタンス変数の参照順

Last updated at Posted at 2020-08-26

イントロ

Pythonにおけるクラス変数とインスタンス変数の概念を説明している際、クラス変数として定義したが、インスタンス変数としては定義していない変数に、インスタンス変数の記法であるself.クラス変数名でアクセスできるのは変ではないか?と気付いた。

→ 簡単なコードを書いてself.クラス変数の挙動を確認した。

分かったこと

Pythonではself.変数名と参照すると、

  1. まずインスタンス変数を参照し、
  2. インスタンス変数が定義されていない場合には、エラーを返す前に同名のクラス変数を参照する。

混濁を避けるため、インスタンス内でクラス変数を参照する場合はクラス名.クラス変数名と記載した方が無難。

サンプルコード

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

4
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3