一个是类属性,而另一个是实例属性。它们是不同的,但是它们之间的紧密联系使它们有时看起来相同。
它与python查找属性的方式有关。有一个层次结构。在简单的情况下,可能看起来像这样:
instance -> Subclass -> Superclass -> object (built-in type)
当您寻找这样的属性时instance
…
`instance.val`
…实际发生的是, 首先 ,Pythonval
在实例本身中进行查找。然后,如果找不到val
,它将在其类中查找Subclass
。然后,如果它没有找到val
那里,它看起来的父母Subclass
,Superclass
。这意味着当您这样做时…
>>> class Foo():
foovar = 10
def __init__(self, val):
self.selfvar = val
…所有Foo
share 实例foovar
,但有各自不同selfvar
的。这是一个简单的具体示例:
>>> 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]