python基础(单例模式)

本文介绍了设计模式的概念,重点讲解了Python中的单例设计模式,目的是确保类只有一个实例,并提供一个全局访问点。详细阐述了如何通过重写__new__方法、使用类方法以及装饰器来实现单例模式,并提供了相关示例代码。

单例设计模式

设计模式:

设计模式是前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对某一特定问题的成熟的解决方案

使用设计模式是为了可重用代码、让代码更容易被他人理解,保证代码可靠性

 

单例设计模式:

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

每一次执行类名()返回的对象,内存地址是相同的

单例设计模式的应用场景:

音乐播放对象

回收站对象

打印机对象

 

__new__方法

使用类名()创建对象时,python的解释器首先会调用__new__方法为对象分配空间

__new__是一个有object基类提供的内置的静态方法,主要作用有两个:

1)在内存中为对象分配空间

2)返回对象的引用

python的解释器获得对象的引用后,将引用作为第一个参数,传递给__init__方法

重写__new__方法的代码非常固定!

重写__new__方法一定要return super().__new__(cls)

否则python的解释器得不到分配了空间的对象引用,就不会调用对象的初始化方法

注意:__new__是一个静态方法,在调用时需要主动传递cls参数

 

python中的单例

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

1.定义一个类属性,初始值是None,用于记录单例对象的引用

2.重写__new__方法

3.如果类属性is None,调用父类方法分配空间,并在类属性中记录结果

4.返回类属性中记录的对象引用

 

只执行一次初始化工作

在每次使用类名()创建对象时,python的解释器都会自动调用两个方法:

__new__分配空间

__init__对象初始化

对__new__方法改造之后,每次都会得到第一次被创建对象的引用

但是:初始化方法还会被再次调用

需求

让初始化动作只被执行一次

解决办法:

1.定义一个类属性init_flag标记是否执行过初始化动作,初始值为False

2.在__init__方法中,判断init_flag,如果为False就执行初始化动作

3.然后将init_flag设置为True

4.这样,再次调用__init__方法时,初始化动作就不会被再次执行了

 

方法一(使用__new__方法):

class MusicPlayer(object):

     instance = None  #记录第一个被创建对象的引用

     init_flag = False  #记录是否执行过初始化动作

 

     def __new__(cls,*args,**kwargs):

           print('创建对象,分配空间')

           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()   #创建第一个实例对象

player2 = MusicPlayer()   #创建第二个实例对象

print(player1,player2)    #打印内存地址,判断是否相同

 

方法二(类方法):

class A():

    _instance = None

    @classmethod

    def class_method(cls, arg):

       if cls._instance == None:

           cls._instance = arg

       return cls._instance

a1 = A.class_method('a')

a2 = A.class_method('b')

print(id(a1), id(a2))

print(A.class_method(1))

 

方法三(为类添加装饰器(单例模式)):

#声明一个容器用于存放对象

obj = {}    #假设存入的对象键名only 值为对象本身 {'only':对象}

def decor(cls):

     def _decor():   #装饰器的操作

          if 'only' in obj:

               return obj['only'] #对象已经创建

           else: 

               obj['only'] = cls()   #对象没有创建,创建对象并返回

               return obj['only']

           return _decor   #返回装饰的操作

#当前类只能实例化一个对象

@decor

class LiXue:

     name = '小雪'

     sex = '女'

     age = '21岁'

     @staticmethod

     def stuPy():

          print('好好学习天天向上!')

 

one = LiXue() #实例化多个对象

two = LiXue()

three = LiXue()

print(one,two,three)  #查看id内存地址是否相同

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值