有没有简单优雅的方法来定义单例?
似乎有很多方法可以在Python中定义单例。关于StackOverflow是否有共识?
解决方案
回答
作为Python的新手,我不确定最常见的习惯用法是什么,但是我能想到的最简单的事情就是使用模块而不是类。类上的实例方法原本只是模块中的函数,而任何数据都只是模块中的变量,而不是类的成员。我怀疑这是解决人们使用单例的问题类型的Python方法。
如果我们真的想要单例类,那么Google首次针对" Python单例"提供了一个合理的实现,具体是:
class Singleton: __single = None def __init__( self ): if Singleton.__single: raise Singleton.__single Singleton.__single = self
这似乎可以解决问题。
回答
我没有真正的需要,因为具有功能(而不是类)的模块可以很好地用作单例。它的所有变量都将绑定到模块,该模块无论如何都无法重复实例化。
如果我们确实希望使用类,则无法在Python中创建私有类或者私有构造函数,因此,我们只能通过使用API的约定来保护自己免受多重实例化的侵害。我仍将方法放在模块中,并将模块视为单例。
回答
这是Peter Norvig的Python IAQ的一个示例。如何在Python中做单例模式? (我们应该使用浏览器的搜索功能查找此问题,没有直接链接,对不起)
同样,Bruce Eckel在他的《 Thinking in Python》一书中也有另一个示例(同样没有直接链接到代码)
回答
在Python中实现单例的方式略有不同,这是Alex Martelli(Google员工,Python天才)的borg模式。
class Borg: __shared_state = {} def __init__(self): self.__dict__ = self.__shared_state
因此,它们不是强制所有实例具有相同的标识,而是共享状态。
回答
模块方法效果很好。如果我绝对需要一个单例,那么我喜欢使用元类方法。
class Singleton(type): def __init__(cls, name, bases, dict): super(Singleton, cls).__init__(name, bases, dict) cls.instance = None def __call__(cls,*args,**kw): if cls.instance is None: cls.instance = super(Singleton, cls).__call__(*args, **kw) return cls.instance class MyClass(object): __metaclass__ = Singleton
回答
有一次我用Python写了一个单例,我使用了一个类,其中所有成员函数都具有classmethod装饰器。
class foo: x = 1 @classmethod def increment(cls, y = 1): cls.x += y
回答
使用ActiveState由Python实现的Singleton模式。
似乎诀窍是将本应仅具有一个实例的类放在另一个类中。
回答
Google测试博客上也有一些有趣的文章,讨论了为什么单例是/可能是不好的并且是反模式的:
- 单身人士是病态的骗子
- 所有的单身人士都去哪儿了?
- 单身人士的根本原因
回答
我对此不太确定,但是我的项目使用"约定单例"(非强制性单例),也就是说,如果我有一个名为" DataController"的类,则可以在同一模块中定义它:
_data_controller = None def GetDataController(): global _data_controller if _data_controller is None: _data_controller = DataController() return _data_controller
它不够优雅,因为它有完整的六行。但是我所有的单例都使用这种模式,并且至少非常显式(这是pythonic的)。
回答
我们可以像这样覆盖__new__
方法:
class Singleton(object): _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super(Singleton, cls).__new__( cls, *args, **kwargs) return cls._instance if __name__ == '__main__': s1 = Singleton() s2 = Singleton() if (id(s1) == id(s2)): print "Same" else: print "Different"
回答
class Singleton(object[,...]): staticVar1 = None staticVar2 = None def __init__(self): if self.__class__.staticVar1==None : # create class instance variable for instantiation of class # assign class instance variable values to class static variables else: # assign class static variable values to class instance variables
回答
请参阅PEP318的此实现,该实现使用装饰器实现单例模式:
def singleton(cls): instances = {} def getinstance(): if cls not in instances: instances[cls] = cls() return instances[cls] return getinstance @singleton class MyClass: ...