[python面向对象学习笔记六] 单例

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>

以上方法,可以让初始化的动作只被执行一次,并不是只调一次初始化方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值