认识单例模式 __new__ __init__

让类的实例在系统中只有一个唯一的实例,每一次执行 类名()返回 的对象,内存地址相同。

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

音乐播放器对象

回收站对象

打印机对象

__new__ 的执行顺序是在__init__之前,因为__new__执行的是类方法所以在__init__之前,__new__要先分配内存空间给对象,然后再把对象的引用给__init__方法。

class Singleton(object):

    def __init__(self,*args,**kwargs):
        print("__init__")

    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            print("instance")
            Singleton._instance = Singleton(*args, **kwargs)
        return Singleton._instance


Singleton.instance(())
instance
__init__
class Musicplayer:

    def __new__(cls, *args, **kwargs):
        print("__new__")
    def __init__(self):
        print("__init__")



player1 = Musicplayer()
__new__

如果不把对象引用返回给__init__则只会执行__new__方法,所以把对象引用返回给__init__.

class Musicplayer:

    def __new__(cls, *args, **kwargs):
        print("__new__")
        return super().__new__(cls)
    def __init__(self):
        print("__init__")



player1 = Musicplayer()
__new__
__init__

class Musicplayer:
    def __init__(self):
        print("播放器")
播放器
<__main__.Musicplayer object at 0x000002535AB0EB70>
播放器
<__main__.Musicplayer object at 0x000002535AB0EC50>

创建两个Musicplayer的对象,他们的内存地址不一样,说明创建了两个播放器对象。

要想创建单例则必须重写__new__方法。

要记住这个流程:

先判断有之前有没有创建实例对象,如果有则继续用这个实例对象的内存的地址,没有则在内存中开辟一个空间给这个第一次创建的实例对象。

class Musicplayer:
    instance = None#对象
    def __new__(cls, *args, **kwargs):
        if cls.instance is None:#判断类属性是否为空对象
            cls.instance = super().__new__(cls)#如果是空则调用父类方法,为第一个对象创建内存空间
        return cls.instance#返回类属性保存的对象引用给__init__
    def __init__(self):
        print("播放器")



player1 = Musicplayer()
print(player1)

player2 = Musicplayer()
print(player2)
播放器
<__main__.Musicplayer object at 0x000002832CBEEC50>
播放器
<__main__.Musicplayer object at 0x000002832CBEEC50>

重写__new__方法后,创建的对象都指向唯一一个内存地址。

单例只初始化一次:

就是在设置一个类属性init_flag = False,在__init__方法下判断init_Flag是否为True,如果是True则return Non,不是就执行第一次初始化的函数,在把init_flag = True。

class Musicplayer:
    instance = None#
    init_flag = False
    def __new__(cls, *args, **kwargs):
        if cls.instance is None:#判断类属性是否为空对象
            cls.instance = super().__new__(cls)#如果是空则调用父类方法,为第一个对象创建内存空间
        return cls.instance#返回类属性保存的对象引用给__init__
    def __init__(self):
        if Musicplayer.init_flag == True:
            return
        print("播放器")
        Musicplayer.init_flag = True
播放器
<__main__.Musicplayer object at 0x0000029B8A67EC50>
<__main__.Musicplayer object at 0x0000029B8A67EC50>

猜你喜欢

转载自blog.csdn.net/u014248032/article/details/84644209