Python(クラス変数とインスタンス変数)

class C:
    # クラス変数
    x=0
    def __init__(self):
        # インスタンス変数
        self.b=0

print(C.x)
a=C()
b=C()
print(a.x)
print(b.x)

# このようにインスタンスからクラス変数を変更するとインスタンス扱いになる
a.x="hello"
print(C.x)
print(a.x)
print(b.x)

class A:
    x=0

    def __del__(self):
        print("デストラクタ")

class B(A):
    def __init__(self):
        self.parent_x=super().x

# インスタンス生成時にコンストラクタで初期化されるので、値は保持されない
print(B().x)
print(A().x)
B().x=10
print(B().x)
print(A().x)
B().parent_x=10
print(B().x)
print(A().x)
print(B().parent_x)

# クラスオブジェクトからクラス変数を書き換え
A.x=100
print(B().x)
print(A().x)
print(B().parent_x)

# クラスインスタンスオブジェクトを保持してインスタンス変数を作成すると、
#そのオブジェクトがあればインスタンス変数の値が保持される
a=A()
print(a.x)
a.x=10
print(a.x)

# インスタンスの破棄
del a

クラス変数はクラス共通の変数として扱われるため、クラスオブジェクトからインスタンスを生成した場合、どのクラスオブジェクト変数から値を参照してもクラスインスタンスの値と同じになるが、クラスインスタンスオブジェクトを保持したインスタンスから変数を書き換えた場合、それはインスタンス変数として新たに登録され、元のクラス変数を扱うことはできなくなるので注意。
基本、インスタンスとして扱う場合の変数はインスタンス変数として定義するようにしましょう。

また、クラスのインスタンス変数はクラス内で定義されていなくても後から追加することができ、ミスタイプで変数名が違ったとしてもエラーが出ずに、新たな変数として登録されてしまうので注意しましょう。

クラスのインスタンス変数はC++と違い、Pythonではガベージコレクションで参照カウンタが0になると自動的にメモリから開放されます。ただ、デストラクタがどのタイミングで呼ばれるかの制御をしたいのであれば、del()メソッドを記述して、任意のタイミングでメモリ開放をしましょう。クラスの特殊メソッド.__del__(self)を定義すればデストラクタ時の振る舞いを定義することができます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

This site uses Akismet to reduce spam. Learn how your comment data is processed.