实现单例模式的5种方式
参考链接🔗https://www.cnblogs.com/liuqingzheng/p/17605093.html
单例模式
该模式的主要目的是确保某一个类只有一个实例存在。
- 模块
- 在 Python 中,模块是天然的单例。将需要实现单例的功能放在一个模块中,然后在其他地方导入该模块,就能保证只有一个实例。
-
# singleton_module.py class Singleton: def __init__(self): pass singleton_instance = Singleton()
- 在其它地方导入该模块
from singleton_module import singleton_instance # 使用 singleton_instance 单例对象
- 装饰器
- 使用装饰器将类转换为单例,通过
@singleton
注解,使得只能创建一个实例。def singleton(cls):
'''这是一个装饰器函数,它接受一个类作为参数cls
。装饰器函数内部定义了一个内部函数get_instance
,用于返回单例实例。在内部函数get_instance
中,使用一个字典instances
来存储不同类的实例,以确保每个类只有一个实例。''' instances = {} def get_instance():
'''这是一个内部函数,在装饰器函数内部定义。get_instance
函数的作用是检查instances
字典中是否已经有当前类的实例。如果没有,则创建一个新的实例,并将其存储在instances
字典中。如果已经存在,则直接返回该实例。''' if cls not in instances: instances[cls] = cls() return instances[cls] return get_instance @singleton
'''在类的定义前面使用装饰器语法@singleton
,将该类传递给装饰器函数singleton
,从而使得该类成为一个单例类。''' class Singleton: def __init__(self): pass# 创建单例对象
singleton_instance = Singleton()让我们看看实际的执行过程
-
@singleton class Singleton: def __init__(self): pass # 创建 Singleton 的实例 instance1 = Singleton() # 因为 Singleton 是单例类,所以再次创建实例会返回之前创建的实例 instance2 = Singleton() print(instance1 is instance2) # 输出: True,说明实际上 instance1 和 instance2 是同一个实例
- 使用装饰器将类转换为单例,通过
- 类方法
- 在 Python 中,类方法是在类上调用而不是在实例上调用的方法。通过使用类方法,可以确保每次调用类方法时都返回同一个实例。
-
class Singleton(object): _instance=None def __init__(self): pass @classmethod def instance(cls, *args, **kwargs): if not cls._instance: cls._instance=cls(*args, **kwargs) return cls._instance a1=Singleton.instance()# 直接通过类调用类方法 a2=Singleton().instance() # 创建了一个实例对象,然后通过这个对象调用类方法 print(a1 is a2)
- 基于new方法实现
__new__
是一个Python中特殊的内置方法,用于创建类的实例。它是在一个类实例化的过程中第一个被调用的方法,它的作用是负责创建并返回一个类的新实例。class Singleton(object): _instance=None def __init__(self): pass def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = object.__new__(cls) return cls._instance obj1 = Singleton() obj2 = Singleton() print(obj1 is obj2)
- 基于metaclass方法实现
- 元类允许你在类定义时对类进行修改和控制,从而实现单例模式的逻辑。
-
class SingletonType(type): _instance=None def __call__(cls, *args, **kwargs): if not cls._instance: cls._instance = object.__new__(cls) cls._instance.__init__(*args, **kwargs) return cls._instance class Foo(metaclass=SingletonType): def __init__(self,name): self.name = name obj1 = Foo('name') obj2 = Foo('name') print(obj1.name) print(obj1 is obj2)