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