python 类属性
我有一个关于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.derived_val
和t2.__class__.derived_val
的内存地址,它们是不同的。我的问题是derived_val
是类属性。为什么在上面的例子中它们会不同呢?是因为类的实例会在自己的地方复制一个derived_val
,而不是直接使用类属性吗?
3 个回答
4
还有一种方法(可能更简洁)来展示这个:
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"], [])
47
在编程中,有两种属性:类属性和实例属性。
当你写
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__
里找这个'derived_val'。如果找不到,它会去t2
的父类里查找是否有这个'derived_val'
的键。
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}
需要注意的是,这时有两个derived_val
属性,但只有实例属性是很容易访问的。类属性只能通过base.derived_val
或者直接访问类字典base.__dict__
来获取。