乐趣区

关于后端:单例设计模式

好买网 IT 技术交易平台
指标:
单例设计模式
__new__办法
Python 中的单例
1. 单例设计模式
设计模式:
设计模式 是 前人工作的总结和提炼,通常,被人们宽泛流传的设计模式,都是针对 某一特定问题 的成熟的解决方案
应用设计模式是为了可重用代码、让代码更容易被别人了解、保障代码可靠性
单例设计模式
目标——让 类创立的对象,在零碎中只有 惟一的一个实例
每一次执行 类名 () 返回的对象,内存地址是雷同的
单例设计模式的利用场景
音乐播放 对象
回收站 对象
打印机 对象
········
2.__new__办法
应用 类名 () 创建对象时,Python 解释器会先调用__new__办法为对象调配空间,再调用__init__() 办法初始化对象
__new__是由 object 基类提供的内置的静态方法,次要作用有两个
在内存中为对象调配空间
返回对象的援用
Python 解释器取得对象的援用后,将援用作为第一个参数,传递给__init__办法

class MusicPlayer(object):
    def __new__(cls, *args, **kwargs):
        print("创建对象,调配空间")

    def __init__(self):
        print("初始化对象")

player = MusicPlayer()
print(player)
'''
运行后果:创建对象,调配空间:能够看出在实例化对象时,先调用了 new 办法为对象开拓空间
None:因为重写了 new 办法,而 new 办法须要将对象的地址传递给 init,
          重写时并没有做,所以没有进行初始化
'''

重写__new__办法的代码十分的固定
肯定要 return super().__new__(cls)
否则 Python 解释器得不到调配了空间的援用,就不会调用对象的初始化办法
留神:__new__是一个静态方法,在调用时须要被动传递 cls 参数

class MusicPlayer(object):
    def __new__(cls, *args, **kwargs):
        #创建对象时,new 办法会主动被调用
        print("创建对象,调配空间")
        #为对象调配空间
        instance = super().__new__(cls)
        #返回对象的援用
        return instance
    def __init__(self):
        print("初始化对象")

player = MusicPlayer()
print(player)
'''
运行后果:创建对象,调配空间
初始化对象
<__main__.MusicPlayer object at 0x000001DC63B9FF10>
'''

单例——让类创立的对象,在零碎中只有惟一的一个实例
定义一个 类属性,初始值是 None,用于记录单例对象的援用
重写 new 办法
如果类属性 is None, 调用父类办法调配空间,并在类属性中记录后果
返回类属性中记录的对象援用

1 #单例设计模式
 2 class MusicPlayer(object):
 3     instance = None     #记录对象的地址
 4     def __new__(cls, *args, **kwargs):
 5         #判断对象是否为空,如果为空,就为其调配地址
 6         if cls.instance is None:
 7             #为对象调配空间
 8             cls.instance = super().__new__(cls)
 9             #返回对象的援用
10             return cls.instance
11         #如果部位空,就返回第一个对象的地址
12         else:
13             return cls.instance
14     def __init__(self):
15         pass
16 
17 player_1 = MusicPlayer()    #<__main__.MusicPlayer object at 0x00000282C8B7FDF0>
18 print(player_1)
19 
20 player_2 = MusicPlayer()    #<__main__.MusicPlayer object at 0x00000282C8B7FDF0>
21 print(player_2)
单例设计模式案例

只执行一次初始化动作
需要:让初始化动作只被执行一次
解决办法
定义一个类属性 init_flag 标记是否 执行过初始化动作,初始值为 False
init 办法中,判断 init_flag, 如果为 False 就执行初始化动作
而后将 init_flag 设置为 True
这样,再次调用__init__办法时,初始化动作就不会被执行了

1 #初始化动作只执行一次
 2 class MusicPlayer(object):
 3     instance = None     #记录对象的地址
 4     init_flag = False   #标记是否执行过初始化动作
 5     def __new__(cls, *args, **kwargs):
 6         #判断对象是否为空,如果为空,就为其调配地址
 7         if cls.instance is None:
 8             #为对象调配空间
 9             cls.instance = super().__new__(cls)
10             #返回对象的援用
11             return cls.instance
12         #如果部位空,就返回第一个对象的地址
13         else:
14             return cls.instance
15     def __init__(self):
16         #判断初始化动作是否执行过
17         if MusicPlayer.init_flag:
18             return
19         #如果没有执行过,那么执行初始化动作
20         print("初始化播放器")
21         #批改类属性(init_flag)的标记
22         MusicPlayer.init_flag = True
23 
24 player_1 = MusicPlayer()    #<__main__.MusicPlayer object at 0x00000282C8B7FDF0>
25 print(player_1)
26 player_2 = MusicPlayer()    #<__main__.MusicPlayer object at 0x00000282C8B7FDF0>
27 print(player_2)
28 player_3 = MusicPlayer()    #<__main__.MusicPlayer object at 0x00000282C8B7FDF0>
29 print(player_3)
30 '''
31 运行后果:32 初始化播放器
33 <__main__.MusicPlayer object at 0x0000029ECB252F10>
34 <__main__.MusicPlayer object at 0x0000029ECB252F10>
35 <__main__.MusicPlayer object at 0x0000029ECB252F10>
36 '''
只执行一次初始化动作
退出移动版