如何在Python中创建单例 在Python中列表和元组的区别 在Python中查找扩展名为.txt的目录中的所有文件 如何在Python中创建单例 方法1:装饰者 def singleton(class_): instances = {} def getinstance(*args, **kwargs): if class_ not in instances: instances[class_] = class_(*args, **kwargs) return instances[class_] return getinstance @singleton class MyClass(BaseClass): pass 优点 装饰器的添加方式通常比多重继承更直观。 缺点 虽然使用MyClass()创建的对象将是真正的单例对象,但MyClass本身是一个函数,而不是一个类,因此您无法从中调用类方法。也适合m = MyClass(); n = MyClass(); o = type(n)();那时m == n && m != o && n != o 方法2:基类 class Singleton(object): _instance = None def __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 优点 这是一个真正的课程 缺点 多重继承 - eugh!__new__在从第二个基类继承期间可能被覆盖?人们必须思考的不仅仅是必要的。 方法3:元类 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] #Python2 class MyClass(BaseClass): __metaclass__ = Singleton #Python3 class MyClass(BaseClass, metaclass=Singleton): pass 优点 这是一个真正的课程 自动神奇地涵盖了继承 使用__metaclass__它的正确用途(使我意识到这一点) 缺点 没有 方法4:装饰器返回一个具有相同名称的类 def singleton(class_): class class_w(class_): _instance = None def __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 = False return class_w._instance def __init__(self, *args, **kwargs): if self._sealed: return super(class_w, self).__init__(*args, **kwargs) self._sealed = True class_w.__name__ = class_.__name__ return class_w @singleton class MyClass(BaseClass): pass 优点 这是一个真正的课程 自动神奇地涵盖了继承 缺点 是否没有创建每个新类的开销?在这里,我们为每个我们希望制作单例的类创建两个类。虽然这在我的情况下很好,但我担心这可能无法扩展。当然,关于是否要过于容易地扩展这种模式存在争议...... 该_sealed属性的重点是什么 无法在基类上调用相同名称的方法,super()因为它们会递归。这意味着您无法自定义__new__并且无法子类化需要您调用的类__init__。 在Python中列表和元组的区别 在Python中查找扩展名为.txt的目录中的所有文件