系列文章目录
文章目录
应用场景举例
现有一个数据库(用输出操作代替写入数据),程序的各个模块都可能要操作数据库(如:查询,保存, … )。
问题分析
- 我们可以创建一个类负责数据库操作
- 因为各个模块都可能要用到数据库操作,所以数据库对象的创建与销毁大概率是很频繁的,但是这两种操作都占有巨大的内存与耗时,如果多次操作肯定会降低程序效率。
单例模式的出场
如果我们把这个类比作 某种职业 ,那么每次创建我们就要招聘 一个员工 ,
销毁就要裁剪掉一个员工,当然还要付给他们工钱 。这样耗时耗力,但是如果我们一心一意,从头到尾只招聘一个员工,那么我们就只需要付给这一个员工工钱,节约了不少成本,这就是单例。
所以我们可以从头到尾只使用一个数据库类的实例化,这样就相当于只招聘了一个员工,实现了单例,节约了时间空间成本。
但是,我们从头到尾只是用一个变量,这也太不科学了,全部加 global
不好吧,所以接下来就要看到我们神奇的实现了
单例模式
定义
单例模式是指:保证一个类仅有一个实例,并提供一个访问它的全局访问点
实现(python)
这里有七种方法实现python中的单例模式,下面 一 一为大家介绍
其实,总的原则就是:保证一个类只要实例化一个对象,下一次再实例的时候就直接返回这个对象,不再做实例化的操作
第一类:模块导入的方式
第一类通过模块导入的方式,借用了模块导入时的底层原理实现。
当一个模块(py文件)被导入时,首先会执行这个模块的代码,然后将这个模块的名称空间加载到内存。
当这个模块第二次再被导入时,不会再执行该文件,而是直接在内存中找。
于是,如果第一次导入模块,执行文件源代码时实例化了一个类,那再次导入的时候,就不会再实例化。
这里只有一种方法:
singleton.py
class Demo(object):
pass
instance = Demo()
test.py
import singleton
demo1 = singleton.instance
demo2 = singleton.instance
print(demo1 is demo2)
输出
True
第二类:通过魔法方法判断的方式
第二类主要是基于类和元类实现,在’对象’的魔法方法中判断是否已经实例化过一个对象
这类方式,根据实现的手法不同,又分为不同的方法,如:
通过类的绑定方法;
通过元类;
通过类下的__new__;
通过装饰器(函数装饰器,类装饰器)实现等。
通过类的绑定方法
class Student:
_instance = None # 记录实例化对象
def __init__(self, name, age):
self.name = name
self.age = age
@classmethod
def get_singleton(cls, *args, **kwargs):
if not cls._instance:
cls._instance = cls(*args, **kwargs)
return cls._instance
stu1 = Student.get_singleton('jack', 18)
stu2 = Student.get_singleton('jack', 18)
print(stu1 is