【进阶12】【自学笔记】Python单例模式实现的几种方式
一、单例模式定义
单例模式是一种常用的创建型设计模式,它保证一个类只有一个实例,并提供一个全局的访问点。
二、实例展示
实例1:
class Singleton: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance
在这个示例中,我们定义了一个名为 Singleton 的类,其中包含了一个类变量 _instance
,初始值为 None
。在 __new__
方法中,我们首先检查 _instance
变量是否为 None
,如果是,则说明当前尚未创建过该类的实例,我们调用父类 super().__new__(cls)
创建一个新的实例,并将其保存在 _instance
中;否则,直接返回已存在的实例。
使用时,我们可以像下面这样来创建 Singleton 的实例:
s1 = Singleton() s2 = Singleton() assert s1 is s2 # True
以上面的代码为例,因为 Singleton 的实例只能有一个,所以 s1 和 s2 其实是同一个实例对象,因此 s1 is s2
的结果为 True
。
实例2:
Python 还提供了一种更简洁的方式来实现单例模式,那就是使用 call 方法。具体而言,我们只需要将要实现单例模式的类定义为一个 callable 对象,并在类中定义 call 方法,这个类的实例就可以像函数一样被调用了
class Singleton: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance def __call__(cls, *args, **kwargs): return cls._instance
在这个示例中,我们定义了一个名为 Singleton 的类,其中包含了一个类变量 _instance
和一个 __call__
方法。在 __call__
方法中,我们直接返回 _instance
变量,这样当我们像调用函数一样调用 Singleton 的实例时,实际上返回的是同一个对象。
使用时,我们可以像下面这样来创建 Singleton 的实例:
s1 = Singleton() s2 = Singleton() assert s1 is s2 # True
以上面的代码为例,因为 Singleton 的实例只能有一个,所以 s1 和 s2 其实是同一个实例对象,因此 s1 is s2
的结果为 True
实例3:
使用装饰器:装饰器可以用于装饰一个类,使其在实例化时返回同一对象。具体实现方式与以上的元类类似。
def singleton(cls): _instances = {} def get_instance(*args, **kwargs): if cls not in _instances: _instances[cls] = cls(*args, **kwargs) return _instances[cls] return get_instance @singleton class MySingleton: pass s1 = MySingleton() s2 = MySingleton() print(s1 is s2) # 输出:True
实例4:
使用模块:Python 中的模块是天然的单例,因为在导入模块时只会执行一次初始化代码,后续的导入操作都是返回同一份已经初始化过的对象。因此可以将需要实现单例的类定义在一个模块中,直接导入该模块即可获得该类的唯一实例。
# singleton.py class MySingleton: pass my_singleton = MySingleton() # 创建唯一实例 # main.py from singleton import my_singleton print(my_singleton) # 输出:<singleton.MySingleton object at 0x7f5d5e9780f0>
以上4种实现方式都可以达到单例模式的效果,其中使用模块的方式代码量最少,但有些情况下可能不太灵活;使用元类和装饰器的方式代码量较多,但可以更加灵活地控制单例的创建过程。
本文来自博客园,作者:橘子偏爱橙子,转载请注明原文链接:https://www.cnblogs.com/xfbk/p/17324485.html