为什么这个Python Borg / Singleton模式有效

时间:2012-08-26 05:52:56

标签: python singleton

我刚刚在网上绊了一下,发现这些有趣的代码被剪掉了:

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]: 

但无法完全理解这种情况会如何发生。

3 个答案:

答案 0 :(得分:12)

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

当你这样做时:

b1.foo = "123"

您正在修改dictb1.__dict__引用的Borg.__shared_state

答案 1 :(得分: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

答案 2 :(得分:3)

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

然而,如果使用is来测试相等性(浅等式),对象仍然会比较不相等,因为它们仍然是不同的实例(很像个别的Borg无人机,它们分享他们的想法,但在物理上是不同的)。 / p>