15 单例模式
15.1 init和new方法
执行步骤
- 实例化一个对象,先执行new方法,在new方法中返回对象
- 然后再调用init方法
15.1.1 __init__方法
__init__ 是构造方法
<font color="red">其实最先调用的方法是new方法</font>,但是大部分情况下是不使用new方法
1class Test(object): 2 def __init__(self): 3 print("这是init方法") 4 5t = Test()
15.1.2 __new__方法
__new__
步骤:实例化对象时,python解释器会先调用new方法为对象分配空间,然后再执行init初始化对象
new方法的作用
-
在内存中为对象分配空间
-
返回对象的引用
python解释器获取对象的引用后,将引用作为第一个参数,传递给init方法
1 2class Person(object): 3 def __init__(self): 4 print("这是init方法") 5 6 def __new__(cls,*args,**kwargs): #cls代表类对象本身 7 print("这是new方法",cls) 8 9 10p = Person() 11print(pe) 12# 运行结果 13# 这是new方法 <class '__main__.Person'> 14# None 15 16注意!!!:并没有执行init方法
第一种写法
1# 重写new方法 2class Person(object): # object提供的new方法 3 def __init__(self): 4 print("init") 5 6 def __new__(cls,*args,**kwargs):#cls表示这个类 7 print("new") # 先执行new方法的代码 8 res = object.__new__(cls) #调用父类的new方法 9 print(res) #res就是实例化后的对象的引用 10 return res #将实例后的结果进行返回 11 12p2 = Person() 13 14# 输出结果 15# new 16# <__main__.Person object at 0x000001C67F368A48> 17# init
第二种写法
1# 重写new方法 2class Person(object): # object提供的new方法 3 def __init__(self): 4 print("init") 5 6 def __new__(cls,*args,**kwargs):#cls表示这个类 7 print("new") # 先执行new方法的代码 8 return super().__new__(cls) 9 10p2 = Person() 11 12# 输出结果 13# new 14# <__main__.Person object at 0x000001C67F368A48> 15# init
**init方法时什么时候被自动调用? **
实例化的时候调用
**new方法是用来创建实例对象,new方法是从哪里来的? **
object这个类出来的
**self里面是什么? **
self代表实例对象本身
15.2 单例模式的介绍
单例模式:是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中系统中,某个类只能出现一个实例。
实现单例模式的方法
- 通过@classmethod
- 通过装饰器实现
- 通过__new__实现 (重点)
- 通过导入模块实现
单例模式设计流程
- 定义一个类属性,初始值为None,用于记录单例对象的引用
- 重写new方法
- 进行判断,如果类属性是None,则new方法返回的对象引用保存进去。
- 返回类属性中记录的对象引用
15.3 使用__new__方法实现单例模式
1# 无论实例化多少次,都实例化一个实例 2 3class Exam(object): 4 # 记录第一个被创建的对象引用 5 ins = None #类属性 6 7 def __init__(self): 8 print("init方法") 9 10 def __new__(cls,*agrs,**kwargs): 11 12 if cls.ins is None: #如果为空,则创建一个 13 cls.ins = object.__new__(cls) 14 15 return cls.ins #返回唯一的实例对象 16 17a = Exam() 18print(a) 19a2 = Exam() 20print(a2) 21
15.4 通过装饰器的方式实现单例模式
通过装饰器的方法来实现
1class Exam(object): 2 ins = None 3 4 5def outer(fn): #被修饰的类名 6 # 创建一个字典来保存类的实例对象 7 ins_dict = {} #{类名:实例,类名2:实例2} 8 9 def inner(): 10 if fn not in ins_dict: #如果字典中没有对象 11 # 创建一个对象,保存在字典中 12 res = fn() #实例化一个对象 13 ins_dict[fn] = res #添加信息 14 return ins_dict[fn] 15 return inner 16 17@outer 18class Animal(object): #单例模式的类 19 pass 20 21t1 = Animal() 22print(t1) 23t2 = Animal() 24print(t2) 25 26
