单例模式实现
单例模式(Singleton Pattern)的核心作用是确保一个类只有一个实例,并且提供一个访问该实例的全局访问点。指无论创建多少次实例,返回的都是一个实例对象,也就是返回的是同一个对象引用,也就是在内存中是一个地址。
单例模式只生成一个实例对象,减少了对系统资源的开销。当一个对象的产生需要比较多的资源,如读取配置文件、产生其他依赖对象时,可以产生一个“单例对象”,然后永久驻留内存中,从而极大的降低开销。
单例模式有多种实现的方式,我们这里推荐重写__new__()的方法。
重构 __new__方法来实现单例模式:
1、定义一个类属性,初始值为None,用于记录单例对象的引用
2、重构 new 方法,new 方法是Python 中 在创建实例对象是被调用,它有两个作用,1、为对象分配空间; 2、返回调用的对象,给 __init__进行初始化,定义对象的属性。
3、在创建对象时,判断如果 类属性 is None ,调用父类方法分配空间,并在类属性中记录结果。
4、如果 类属性 不是 None ,则直接 返回创造好的 对象的引用。
流程图如下:
'''
单例模式的实现
'''
class Mysingleton(object):
__obj = None
__init_flag = True
def __new__(cls,*args,**kwargs):
#通过判断来实行多个对象只返回一个引用
if cls.__obj is None:
cls.__obj = super().__new__(cls) # 重写__new__方法,分配空间
return cls.__obj # 如果不为 none,返回同一个对象的引用
#上面的代码已经实现了单例模式,下面是让初始化执行一次
def __init__(slef):
if slef.__init_flag:
print("我初始化了")
slef.__init_flag = False
a = Mysingleton()
print(a)
b = Mysingleton()
print(b)
代码输出结果:
我初始化了
<main.Mysingleton object at 0x0203F8B0>
<main.Mysingleton object at 0x0203F8B0>
Process finished with exit code 0
从输出结果来看,创建了两个对象 a 和 b ,它俩都输出的是同一个地址。
从而实现了多个对象 只有一个实例对象。
单例模式的应用场景 是 windows 的回收站业务,就是创建的是一个对象。
实现单例模式的方法
- 使用模块
- 使用 new
- 使用装饰器 (decorator)
- 使用元类(metaclass)
1、使用模块
其实,python 的模块就是天然的单例模式
因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入的时候,就会直接加载 .pyc 文件,而不是再次执行模块代码,因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。
# test1.py
class Myclass(object):
def fun(self):
print('Myclass.foo')
Myclass_obj = Myclass()
将上面的代码保存在文件, test1.py 中,然后使用:
from test1 import Myclass_obj
Myclass_obj.foo()
2、使用 new 方法,上面讲过
3、使用装饰器
装饰器可以动态地修改一个类和函数的功能,这里,我们也可以使用装饰器来装饰一个类,使用只能生成一个实例。
from functools import wraps
def singleton(cls):
instances = {}
@wraps(cls)
def getinstance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return getinstance
@singleton
class MyClass(object):
a = 1
4、使用元类
参考链接 参考博客