2

我只是在网上偶然发现这些有趣的代码被剪掉了:

http://code.activestate.com/recipes/66531/

class Borg:
    __shared_state = {}
    def __init__(self):
        self.__dict__ = self.__shared_state
    # and whatever else you want in your class -- that's all!

我了解单例是什么,但我不明白特定的代码被剪断了。你能解释一下“__shared_state”是如何/在哪里改变的吗?

我在 ipython 中尝试过:

In [1]: class Borg:
   ...:         __shared_state = {}
   ...:     def __init__(self):
   ...:             self.__dict__ = self.__shared_state
   ...:     # and whatever else you want in your class -- that's all!
   ...: 
In [2]: b1 = Borg()
In [3]: b2 = Borg()
In [4]: b1.foo="123"
In [5]: b2.foo
Out[5]: '123'
In [6]: 

但不能完全理解这是怎么发生的。

4

3 回答 3

12

因为类的实例__dict__被设置为等于__share_state字典。它们指向同一个对象。(Classname.__dict__包含所有类属性)

当你这样做时:

b1.foo = "123"

您正在修改dict两者b1.__dict__Borg.__shared_state参考。

于 2012-08-26T05:58:00.887 回答
3

__init__方法在实例化任何对象后调用,将__dict__新创建的对象的属性替换为类属性__shared_state

a.__dict__,都是同一个对象b.__dict__Borg._Borg__shared_state请注意,_Borg当从类外部访问私有属性时,我们必须添加隐式前缀。

In [89]: a.__dict__ is b.__dict__ is Borg._Borg__shared_state
Out[89]: True
于 2012-08-26T06:03:15.903 回答
3

实例是单独的对象,但是通过将它们的__dict__属性设置为相同的值,实例具有相同的属性字典。Python 使用属性字典来存储对象上的所有属性,因此实际上这两个实例的行为方式相同,因为对其属性的每次更改都是对共享属性字典进行的。

However, the objects will still compare unequal if using is to test equality (shallow equality), since they are still distinct instances (much like individual Borg drones, which share their thoughts but are physically distinct).

于 2012-08-26T06:08:53.853 回答