【进阶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
 

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号