我有多个类将成为单例(我的用例是用于记录器,但这并不重要)。当我可以简单地继承或装饰时,我不希望用添加的gumph杂乱几个类。
最佳方法:
def singleton(class_):instances = {}def getinstance(*args, **kwargs):if class_ not in instances:instances[class_] = class_(*args, **kwargs)return instances[class_]return getinstance
@singletonclass MyClass(BaseClass):pass
优点
缺点
虽然使用MyClass()
创建的对象将是真正的单例对象,但MyClass
本身是一个函数,而不是一个类,因此您不能从中调用类方法。也为了
x = MyClass();y = MyClass();t = type(n)();
然后x == y
但是x != t && y != t
class Singleton(object):_instance = Nonedef __new__(class_, *args, **kwargs):if not isinstance(class_._instance, class_):class_._instance = object.__new__(class_, *args, **kwargs)return class_._instance
class MyClass(Singleton, BaseClass):pass
优点
缺点
__new__
可能会在从第二个基类继承时被覆盖?人们必须多加考虑。class Singleton(type):_instances = {}def __call__(cls, *args, **kwargs):if cls not in cls._instances:cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)return cls._instances[cls]
#Python2class MyClass(BaseClass):__metaclass__ = Singleton
#Python3class MyClass(BaseClass, metaclass=Singleton):pass
优点
__metaclass__
的正确目的(并让我意识到它)缺点
def singleton(class_):class class_w(class_):_instance = Nonedef __new__(class_, *args, **kwargs):if class_w._instance is None:class_w._instance = super(class_w,class_).__new__(class_,*args,**kwargs)class_w._instance._sealed = Falsereturn class_w._instancedef __init__(self, *args, **kwargs):if self._sealed:returnsuper(class_w, self).__init__(*args, **kwargs)self._sealed = Trueclass_w.__name__ = class_.__name__return class_w
@singletonclass MyClass(BaseClass):pass
优点
缺点
_sealed
属性的重点是什么super()
在基类上调用同名方法,因为它们会递归。这意味着您不能自定义__new__
,也不能子类化需要您最多调用__init__
的类。模块文件singleton.py
优点
缺点