单例模式
简介
创建对象时,每次返回的对象都是同一个对象,即类只有唯一实例,每次实例化返回的对象,内存地址都是相同的
应用
- 音乐播放器
- 回收站
- 打印机
__new__方法
- 使用类名()创建对象时,python解释器首先会调用__new__方法为对象分配空间
-
__new__
是一个由object
对象提供的 内置静态方法,要的作用有两个:- 在内存中为对象 分配空间
- 返回对象的引用
-
python解释器获得对象引用后,将引用作为第一个参数,传递给
__init__
方法
重写__new__方法
- 重写__new__方法,一定要
return super().__new__(cls)
- 否则python的解释器得不到分配的空间引用对象,无法调用对象的初始化方法
-
__new__
是一个静态方法,在嗲用对象时,需要主动传递cls参数
Python中的单例
- 单例 – 让类创建的对象,在系统中只有一个实例
- 定义一个类属性,初始值是
None
,用于记录对象的引用 - 重写
__new__
方法 - 如果类属性 is None 为 True,调用父类
__new__
方法为对象分配空间,并让类属性记录结果 - 返回类属性中对象的引用
- 定义一个类属性,初始值是
class MusicPlayer:
instance = None
def __new__(cls, *args, **kwargs):
if cls.instance is None:
cls.instance = super().__new__(cls)
return cls.instance
def __init__(self):
print("播放器初始化")
player1 = MusicPlayer()
print(player1)
player2 = MusicPlayer()
print(player2)
单例模式的改造
- 上述代码中,无论实例化多少个对象,即使实例化的为同一个对象,
__init__
方法仍旧会被多次调用 - 需求:单例模式下,只初始化一次对象
- 解决方案:
- 定义一个类属性
init_flag
,标记是否执行过初始化动作,初始值为False
- 在
__init__
方法中,判断init_flag
,如果为False
就执行初始化操作 - 然后将
init_flag
设置为True
- 再次调用时,根据
init_flag
的值,判断是否需要再次执行__init__
方法
- 定义一个类属性
class MusicPlayer:
instance = None
init_flag = False
def __new__(cls, *args, **kwargs):
if cls.instance is None:
cls.instance = super().__new__(cls)
return cls.instance
def __init__(self):
if MusicPlayer.init_flag:
return
print("播放器初始化")
MusicPlayer.init_flag = True
player1 = MusicPlayer()
print(player1)
player2 = MusicPlayer()
print(player2)