在Python中似乎有很多方法来定义单例对象。对Stack Overflow是否有一致的意见?


当前回答

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

其他回答

如果你想继续装饰(注释)类,创建一个单例装饰器(又名注释)是一种优雅的方式。然后将@singleton放在类定义之前。

def singleton(cls):
    instances = {}
    def getinstance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return getinstance

@singleton
class MyClass:
    ...

我对此非常不确定,但我的项目使用'惯例单例'(不是强制单例),也就是说,如果我有一个名为DataController的类,我在同一个模块中定义这个:

_data_controller = None
def GetDataController():
    global _data_controller
    if _data_controller is None:
        _data_controller = DataController()
    return _data_controller

它并不优雅,因为它足足有六行。但是我所有的单例都使用这个模式,而且它至少是非常显式的(这是python的)。

正如公认的答案所说,最常用的方法是只使用一个模块。

考虑到这一点,下面是一个概念的证明:

def singleton(cls):
    obj = cls()
    # Always return the same object
    cls.__new__ = staticmethod(lambda cls: obj)
    # Disable __init__
    try:
        del cls.__init__
    except AttributeError:
        pass
    return cls

有关__new__的更多详细信息,请参阅Python数据模型。

例子:

@singleton
class Duck(object):
    pass

if Duck() is Duck():
    print "It works!"
else:
    print "It doesn't work!"

注:

为此,您必须使用new-style类(派生自object)。 单例在定义时初始化,而不是在第一次使用时初始化。 这只是一个简单的例子。我从未在产品代码中实际使用过它,也不打算这样做。

我的简单解决方案是基于函数参数的默认值。

def getSystemContext(contextObjList=[]):
    if len( contextObjList ) == 0:
        contextObjList.append( Context() )
        pass
    return contextObjList[0]

class Context(object):
    # Anything you want here

在Python中实现单例的一个稍微不同的方法是Alex Martelli(谷歌员工和Python天才)的borg模式。

class Borg:
    __shared_state = {}
    def __init__(self):
        self.__dict__ = self.__shared_state

因此,它们共享状态,而不是强制所有实例具有相同的标识。