<p>类与类的实例是不同的对象。类有属性,实例有属性。每次尝试访问实例的属性时,如果实例没有该属性,则会在类中查找该属性。如果在实例上设置属性,它总是在实例上设置的,即使这意味着它在类上隐藏了一个同名的属性。你知道吗</p>
<p>在IBAN类中,您在<em>类</em>上定义了一个属性<code>ISOcode</code>。执行<code>numberOne.ISOcode = 'ES'</code>操作时,在<em>实例</em>上设置一个<em>新的</em>属性。您已经将<code>numberOne.ISOcode</code>的值与<code>IBAN.ISOcode</code>的值解耦。但是您创建的任何新实例(如<code>numberTwo</code>)仍然没有自己的实例等位码。然后设置<code>IBAN.ISOcode</code>时,您正在更改<em>类</em>属性。你知道吗</p>
<p>您可以将class属性视为“default”。在执行<code>obj.attr</code>操作时,如果<code>obj</code>没有自己的属性<code>attr</code>,则它将采用类当时的值。如果更改类的属性值,则更改默认值;如果稍后尝试访问没有自己属性的实例上的属性,则它们将看到您创建的新默认值。你知道吗</p>
<p>下面是一个更精简的示例:</p>
<pre><code>>>> class Foo(object):
... attr = "Something"
>>> one = Foo()
>>> two = Foo()
</code></pre>
<p>首先,所有的值都相同,因为我没有指定任何特定于实例的值,所以<code>one</code>和<code>two</code>都从类中获取它们的值。你知道吗</p>
<pre><code>>>> Foo.attr
'Something'
>>> one.attr
'Something'
>>> two.attr
'Something'
</code></pre>
<p>现在我只为<code>one</code>设置一个新值。这不会影响<code>Foo</code>,而且<code>two</code>仍然从<code>Foo</code>获取其值,因此<code>two</code>也不会受到影响。你知道吗</p>
<pre><code>>>> one.attr = "This is only for #1"
>>> Foo.attr
'Something'
>>> one.attr
'This is only for #1'
>>> two.attr
'Something'
</code></pre>
<p>现在我将在类<code>Foo</code>上设置一个新值。这不会影响<code>one</code>,因为<code>one</code>有它自己的值。但是由于<code>two</code>没有它自己的值,它从类中获取它的值,并且因为我更改了类的值,所以这会更改我从<code>two</code>中获取的值:</p>
<pre><code>>>> Foo.attr = "This is the class value"
>>> Foo.attr
'This is the class value'
>>> one.attr
'This is only for #1'
>>> two.attr
'This is the class value'
</code></pre>
<p>要记住的是,每次属性查找都是在执行时动态计算的。创建实例不会自动将类属性从类复制到实例。当您访问实例上的属性时,实例会对自己说“我有自己的属性吗?如果是,则返回该值。如果不是,则返回类的值。”每当您尝试访问一个属性时,它都会问自己这个问题;实例在任何时候都不会与类“独立”。你知道吗</p>