1.概念
设计模式:针对某一特定问题的套路,或者说是成熟的解决方案,前任工作的总结。
单例设计模式:其目的:让类创建的对象,在系统中只有唯一的实例。就是,每次执行类名()创建对象的时候,创建的对象的内存地址都是一样的。
2.__new__方法
__类名__这位格式的方法为内置方法,__new__为object基类提供的内置的静态方法。
__new__方法的作用:在内存为对象分配空间、返回对象的引用。将引用传给python解释器后,会将引用作为对象的第一个参数,传给__init__方法,进行对象的初始化。
每次使用类名()创建对象的时候,解释器会自动调用两个方法:__new__分配空间、__init__对象初始化
__new__方法重写:代码非常固定,一定加上return super(). __new __(cls)。否则,解释器得不到对象引用。注意new方法是一个静态方法,需要主动传入cls参数。
重写的语法:
class MusicPlayer(object):
def __new__(cls, *args, **kwargs): # 一个*表示多值的元组参数,两个*表示多值字典参数
# 1.为证实创建对象时,new方法会自动调用
print("创建对象,分配空间")
# 2.为对象分配空间
instance = super().__new__(cls) # 调用父类的new方法
# 3.返回对象的引用
return instance
def __init__(self):
print("播放器初始化")
# 创建播放器对象
player = MusicPlayer()
print(player)
输出:
创建对象,分配空间
播放器初始化
<__main__.MusicPlayer object at 0x0000019D74091288>
3.单例
思路:
(1)定义一个类属性,初始值为None(空对象),记录创建的第一个对象的引用。
(2)重写__new__方法。如果类属性 is None,调用父类分配空间,并记录在类属性中;否则返回类属性中记录的引用。
class MusicPlayer(object):
instance = None # 定义类属性,记录第一个对象的引用
def __new__(cls, *args, **kwargs):
if cls.instance is None: # 说明第一个对象还没有被创建
cls.instance = super().__new__(cls) # 调用父类方法,为第一个对象分配空间
return cls.instance
else: # 若对象不是第一个
return cls.instance # 返回类属性中保存的对象引用
player1 = MusicPlayer()
print(player1)
player2= MusicPlayer()
print(player2)
输出:
<__main__.MusicPlayer object at 0x000001CCB831DB48>
<__main__.MusicPlayer object at 0x000001CCB831DB48>
以上方法,可以实现对象的内存地址是一样的。但是会多次调用初始化方法。
扩展---------需求:只执行一次初始化方法
class MusicPlayer(object):
instance = None
init_flag = False # 记录是否执行过初始化动作
def __new__(cls, *args, **kwargs):
if cls.instance is None: # 说明第一个对象还没有被创建
cls.instance = super().__new__(cls) # 调用父类方法,为第一个对象分配空间
return cls.instance
else: # 若对象不是第一个
return cls.instance # 返回类属性中保存的对象引用
def __init__(self):
if MusicPlayer.init_flag is False: # 通过类名. 的方式调用类属性
MusicPlayer.init_flag = True
print("初始化播放器") # 执行初始化动作
else:
return
player1 = MusicPlayer()
print(player1)
player2= MusicPlayer()
print(player2)
输出:
初始化播放器
<__main__.MusicPlayer object at 0x0000022AC77E1388>
<__main__.MusicPlayer object at 0x0000022AC77E1388>
以上方法,可以让初始化的动作只被执行一次,并不是只调一次初始化方法。