单例设计模式

好买网 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参数单例设计模式_第1张图片

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,调用父类方法分配空间,并在类属性中记录结果
返回类属性中记录的对象引用单例设计模式_第2张图片

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 '''
只执行一次初始化动作

你可能感兴趣的:(后端python)