<p>你在那里做的事情很有趣,它基于可变性:</p>
<p>声明的初始<code>__shared_state</code>是在执行任何代码之前创建的。该字典称为Class属性,因为它链接到类,而不是实例(不使用<code>self</code>进行声明)。这意味着<code>__shared_state</code>在<code>b1</code>和<code>b2</code>之间共享,因为它是在它们之前创建的,并且因为它是一个<code>dict</code>,所以它是可变的</p>
<h2>什么是可变的</h2>
<p>这意味着分配给两个不同实例的一个字典将引用相同的内存地址,即使我们更改了听写,内存地址也将保持不变。这是一个探针:</p>
<pre class="lang-py prettyprint-override"><code>class Example:
__shared_state = {1: 1}
def __init__(self):
self.__dict__ = self.__shared_state
print(self.__shared_state)
ex1 = Example()
ex2 = Example()
print(id(ex1.__dict__), id(ex2.__dict__))
# Prints
# {1: 1}
# {1: 1}
# 140704387518944 140704387518944
</code></pre>
<p>注意到他们是如何拥有相同的id的吗?这是因为它们引用的是同一个对象,而且<code>dictionary</code>类型是可变的,在一个对象中更改字典意味着您正在更改这两个对象的字典,因为它们是相同的:</p>
<pre class="lang-py prettyprint-override"><code># Executing this
ex1.val1 = 2
# Equals this
ex1.__dict__['val1'] = 2
# Which also equals this
Example.__shared_state['val1'] = 2
</code></pre>
<p>这不会发生在不可变的整数上:</p>
<pre class="lang-py prettyprint-override"><code>class Example:
__shared_state = 2
def __init__(self):
self.a = self.__shared_state
print(self.__shared_state)
ex1 = Example()
ex2 = Example()
ex2.a = 3
print(id(ex1.a), id(ex2.a))
# Prints
# 2
# 2
# 9302176 9302208
# Notice that once we change ex2.a, its ID changes!
</code></pre>
<p>当你删除你的<code>__shared_state</code>时,当你分配<code>b1.val1 = 'Jaga Gola!!!'</code>和<code>b1.val2 = 'BOOOM!!!'</code>时,它只是从<code>b1</code>分配给字典,这就是为什么当你试图打印<code>b2.val1</code>和<code>b2.val2</code>时会出现错误</p>