2010-05-27 56 views
13

我有一个关于python中的class属性的问题。python class属性

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。 .derived_val具有不同的内存地址。 我的问题是derived_val是类的属性。为什么在上面的例子中有所不同? 是因为类的实例在类属性旁边复制自己的derived_val?

回答

34

有类属性和实例属性。 当你说

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试图找到 'derived_val' 在t2.__dict__。由于它不在那里,它看起来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__才能访问。

2

检查出herehere

__class__属性是对象所属的类。所以在你的例子中,情况类似于静态变量。 t2.__class__.derived_val指的是属于该类的变量,而不是属于t2的变量。

1

另一种方式(可能是一个更简洁的一个),以证明这一点:

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"], []) 
相关问题