一个是类属性,另一个是实例属性。它们是不同的,但它们彼此密切相关,有时使它们看起来很相似。
它与 python 查找属性的方式有关。有一个层次结构。在简单的情况下,它可能看起来像这样:
instance -> Subclass -> Superclass -> object (built-in type)
当你寻找一个属性时instance
像这样...
`instance.val`
...实际发生的情况是first, Python 寻找val
在实例本身中。然后,如果没有找到val
,它看起来在同类中,Subclass
。然后,如果没有找到val
在那里,它看起来在父项中Subclass
, Superclass
。这意味着当您执行此操作时...
>>> class Foo():
foovar = 10
def __init__(self, val):
self.selfvar = val
...的所有实例Foo
share foovar
,但又有自己独特的selfvar
s。这是一个简单、具体的示例来说明其工作原理:
>>> f = Foo(5)
>>> f.foovar
10
>>> Foo.foovar
10
如果我们不碰触foovar
,两者都是一样的f
and 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]