pythonのクラス属性について質問があります。
class base :
def __init__ (self):
pass
derived_val = 1
t1 = base()
t2 = base ()
t2.derived_val +=1
t2.__class__.derived_val +=2
print t2.derived_val # its value is 2
print t2.__class__.derived_val # its value is 3
結果は異なります。また、id()関数を使用して、t2。派生型valとt2を検索します。クラス。派生型valのメモリアドレスが異なります。私の問題は、derived_valがクラス属性であるということです。上記の例でなぜ違うのですか?クラスのインスタンスがクラス属性の横にある独自のderivated_valをコピーするためですか?
クラス属性とインスタンス属性があります。あなたが言う時
class base :
derived_val = 1
クラス属性を定義しています。 derived_val
はbase.__dict__
のキーになります。
t2=base()
print(base.__dict__)
# {'derived_val': 1, '__module__': '__main__', '__doc__': None}
print(t2.__dict__)
# {}
t2.derived_val
Pythonはt2.__dict__
で 'derivated_val'を見つけようとします。そこにないので、'derived_val'
キーがあるかどうかを調べます。 t2
の基本クラスのいずれか。
print(t2.derived_val)
print(t2.__dict__)
# 1
# {}
ただし、t2.derived_val
に値を割り当てると、インスタンス属性がt2
に追加されます。 derived_val
キーがt2.__dict__
に追加されます。
t2.derived_val = t2.derived_val+1
print(t2.derived_val)
print(t2.__dict__)
# 2
# {'derived_val': 2}
この時点で、2つのderived_val
属性がありますが、簡単にアクセスできるのはインスタンス属性のみであることに注意してください。クラス属性は、base.derived_val
を参照するか、クラスdict base.__dict__
に直接アクセスすることによってのみアクセス可能になります。
これを実証する別の方法(おそらくより簡潔な方法):
class A():
a1 = []
x = A()
y = A()
x.a1.append("test")
x.a1, y.a1
(['test'], ['test'])
class B():
b1 = None
def __init__(self):
self.b1 = list()
r = B()
s = B()
r.b1.append("test")
r.b1, s.b1
(["test"], [])