我一直在阅读布鲁斯·埃克尔在Python中的思考.目前,我正在阅读模式概念章节.在本章中,Eckel展示了python中Singletons的不同实现.但是我对Alex Martelli的Singleton代码(利用继承,而不是私有的嵌套类)有一个不清楚的理解.
这是我对目前代码的理解:
所有Singleton对象都是Borg的子类
_shared_state最初是一个空字典
_shared_state是一个全局变量; 使用Borg的任何对象都具有相同的_shared_state值
到目前为止我的困惑:
这是什么行的目的:self.__dict__ = self._shared_state
; 或者字典的目的
Singletons的所有对象最终是如何具有相同的val,即使它们都是该类的不同实例.
总的来说,我不知道博格是如何运作的
许多人提前感谢!
- 三
*更新:每个Singleton对象创建后_shared_state中存储的内容是什么?
#: Alex' Martelli's Singleton in Python class Borg: _shared_state = {} def __init__(self): self.__dict__ = self._shared_state class Singleton(Borg): def __init__(self, arg): Borg.__init__(self) self.val = arg def __str__(self): return self.val x = Singleton('sausage') print x y = Singleton('eggs') print y z = Singleton('spam') print z print x print y print ´x´ print ´y´ print ´z´ output = ''' sausage eggs spam spam spam <__main__.Singleton instance at 0079EF2C> <__main__.Singleton instance at 0079E10C> <__main__.Singleton instance at 00798F9C> '''
Alex Martell.. 10
到目前为止,答案很好,但让我也直接回答...... self.__dict__
保持实例的属性(即状态)self
(除非它的类具有特殊的东西,如定义__slots__
;-).因此,通过确保所有实例都具有相同的性能,__dict__
我们确保它们都具有相同的属性,即完全相同的状态.因此,Borg是一般Monostate模式的巧妙Python实现,但没有Robert Martin在他的关于C++ Monostate的文章中发现的任何缺点.
另请参阅Monostate与Singleton的这个SO线程 - 当然,大多数讨论与Python无关(显然在Python中Borg不会妨碍继承,相反!)但是Singleton可以非常透明谢谢例如__new__
,所以权衡是完全不同的......).
最有趣的事情?自从我第一次构思Borg以来的8年多(在现任Mozilla Messaging首席执行官大卫·阿舍尔之前,提出了酷博格的名字)我有机会使用任何类型的单身人士或单身人士,可能共四次 - 以及三次在这四个中我很快就重新构建了一个更灵活的方法! - )(第四次是一个子系统,它没有证明非常成功,也没有得到太多的后续工作/维护;-).
第二个最有趣的事情是,Guido,个人,厌恶博格;-).并不是说他对Singleton有任何真正的喜欢:他认为在Python中"单一性",如果需要,应该作为一个模块完成(或者,我想补充一下,伪装成模块的类实例 - 参见例如我的Python中的第7.2.6节中的观察,例如在这个盗版中;-).但是,博格似乎特别冒犯了他的设计美学! - )奇怪,因为他根据我的五件易文章提名我的PSF会员资格,这基本上都是关于博格(及其变体和考虑因素)......! - ).好吧,猜猜他可以"讨厌罪恶而爱死罪人",嗯? - )
到目前为止,答案很好,但让我也直接回答...... self.__dict__
保持实例的属性(即状态)self
(除非它的类具有特殊的东西,如定义__slots__
;-).因此,通过确保所有实例都具有相同的性能,__dict__
我们确保它们都具有相同的属性,即完全相同的状态.因此,Borg是一般Monostate模式的巧妙Python实现,但没有Robert Martin在他的关于C++ Monostate的文章中发现的任何缺点.
另请参阅Monostate与Singleton的这个SO线程 - 当然,大多数讨论与Python无关(显然在Python中Borg不会妨碍继承,相反!)但是Singleton可以非常透明谢谢例如__new__
,所以权衡是完全不同的......).
最有趣的事情?自从我第一次构思Borg以来的8年多(在现任Mozilla Messaging首席执行官大卫·阿舍尔之前,提出了酷博格的名字)我有机会使用任何类型的单身人士或单身人士,可能共四次 - 以及三次在这四个中我很快就重新构建了一个更灵活的方法! - )(第四次是一个子系统,它没有证明非常成功,也没有得到太多的后续工作/维护;-).
第二个最有趣的事情是,Guido,个人,厌恶博格;-).并不是说他对Singleton有任何真正的喜欢:他认为在Python中"单一性",如果需要,应该作为一个模块完成(或者,我想补充一下,伪装成模块的类实例 - 参见例如我的Python中的第7.2.6节中的观察,例如在这个盗版中;-).但是,博格似乎特别冒犯了他的设计美学! - )奇怪,因为他根据我的五件易文章提名我的PSF会员资格,这基本上都是关于博格(及其变体和考虑因素)......! - ).好吧,猜猜他可以"讨厌罪恶而爱死罪人",嗯? - )
class Borg: _shared_state = {} def __init__(self): self.__dict__ = self._shared_state
1)因为Borg._shared_state
在类级别(而不是在__init__
)初始化,它实际上是静态的,例如由类的所有实例共享.
2)self.__dict__
是所有对象都有的字典; 它包含所有实例属性.从而,
self.a=1 assert(self.a == self.__dict__['a']) #True
3)注意,Borg表示"所有实例共享相同的状态",单例表示"只有一个实例".这几乎是同样的效果. Alex Martelli指出Borg是一个pythonic Monostate,因此请参阅Monostate vs Singleton on SO.
似乎他的Singleton类更恰当地命名
class ThisClassHasSingletonBehavior(Borg): ....
因为
<__main__.Singleton instance at 0079EF2C> <__main__.Singleton instance at 0079E10C> <__main__.Singleton instance at 00798F9C>
证明x,y,z不是同一个实例,即使它们共享相同的状态.所以它不是单身,它只是具有相同的整体效果,而且很容易.AFAICT Borg是一个优雅的python模式,用于共享状态(相同状态)行为,其中Singleton是一个优雅的cpp模式.并不是说这种行为是优雅的.