单例设计模式

 好买网 goodmai。com IT技术交易平台

目标:

  1. 单例设计模式
  2. __new__方法
  3. Python中的单例

1.单例设计模式

  • 设计模式:
    • 设计模式 是 前人工作的总结和提炼,通常,被人们广泛流传的设计模式,都是针对 某一特定问题 的成熟的解决方案
    • 使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性
  • 单例设计模式
    • 目的——让 创建的对象,在系统中只有 唯一的一个实例
    • 每一次执行 类名() 返回的对象,内存地址是相同的
  • 单例设计模式的应用场景
    • 音乐播放 对象
    • 回收站 对象
    • 打印机 对象
    • ········

2.__new__方法

  • 使用 类名() 创建对象时,Python解释器会先调用__new__方法为对象分配空间,再调用__init__()方法初始化对象
  • __new__是由object基类提供的内置的静态方法,主要作用有两个
    1. 在内存中为对象分配空间
    2. 返回对象的引用
  • 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__方法的代码非常的固定
  1. 一定要  return super().__new__(cls)
  2. 否则Python解释器得不到分配了空间的引用,就不会调用对象的初始化方法
  3. 注意:__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>
'''

 单例——让类创建的对象,在系统中只有唯一的一个实例

  1. 定义一个 类属性,初始值是None,用于记录单例对象的引用
  2. 重写new方法
  3. 如果类属性 is None,调用父类方法分配空间,并在类属性中记录结果
  4. 返回类属性中记录的对象引用

    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)
    
    单例设计模式案例

     只执行一次初始化动作

  5. 需求:让初始化动作只被执行一次
  6. 解决办法
    1. 定义一个类属性init_flag标记是否 执行过初始化动作,初始值为False
    2. 在 __init__ 方法中,判断init_flag,如果为False就执行初始化动作
    3. 然后将init_flag设置为True
    4. 这样,再次调用__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 '''
      
      只执行一次初始化动作

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值