一个是一个类属性,另一个是一个实例属性。它们是不同的,但是它们之间的关系密切相关,使得它们在时间上看起来一样。
它与python查找属性的方式有关。有层次结构。在简单的情况下,它可能如下所示:
instance -> Subclass -> Superclass -> object (built-in type)
当你在这样的实例上寻找属性时…
`instance.val`
…实际发生的是,首先,Python在实例本身中寻找val。然后,如果它没有找到val,它会在它的类,Subclass中。那么,如果没有找到val,那么它会在Subclass,Superclass的父项中查找。这意味着当你这样做…
>>> class Foo():
foovar = 10
def __init__(self, val):
self.selfvar = val
…所有Foo分享foovar的实例,但有自己独特的自我。这是一个简单,具体的例子,它的工作原理:
>>> f = Foo(5)
>>> f.foovar
10
>>> Foo.foovar
10
如果我们不碰foovar,f和Foo都是一样的。但是如果我们改变f.foovar …
>>> f.foovar = 5
>>> f.foovar
5
>>> Foo.foovar
10
…我们添加一个实例属性来有效地掩盖Foo.foovar的值。现在,如果我们直接更改Foo.foovar,它不会影响我们的foo实例:
>>> Foo.foovar = 7
>>> f.foovar
5
但它确实会影响一个新的foo实例:
>>> Foo(5).foovar
7
还要记住,可变对象添加了另一层间接(如mgilson提醒我)。这里,f.foovar指的是与Foo.foovar相同的对象,所以当你改变对象时,更改会传播到层次结构上:
>>> Foo.foovar = [1]
>>> f = Foo(5)
>>> f.foovar[0] = 99
>>> Foo.foovar
[99]