python单例模式

 

定义

  • 目的:让类创建的对象,在系统中只有唯一的实例
  • 每一次执行新建对象操作,返回的都是同一个对象

__new__ 方法

  使用 classname() 创建对象时,Python 的解释器首先会调用 __new__ 方法为对象分配内存空间__new__ 方法是object基类提供的内置静态方法,主要作用有两个:

  • 为对象分配内存空间
  • 返回对象的引用

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

  重写 __new__ 方法时,一定要 return super().__new__(cls),否则 Python 解释器得不到分配了空间的对象引用就不会调用对象的初始化方法

复制代码
class MusicPlayer(object):

    def __new__(cls, *args, **kwargs):
        return super().__new__(cls,*args,**kwargs)

    def __init__(self):
        print("初始化音乐播放对象")

player = MusicPlayer()

print(player)
复制代码

 

实现单例

  让系统中只存在唯一实例

复制代码
class MusicPlayer(object):

    # 定义类属性记录单例对象引用
#java中空引用为null,Python中判断不为空的语句为:if instance is not None:
instance = None
def __new__(cls, *args, **kwargs):

        # 1. 判断类属性是否已经被赋值
        if cls.instance is None:
            cls.instance = super().__new__(cls)

        # 2. 返回类属性的单例引用
        return cls.instance
复制代码

每次使用 classname() 创建对象时,Python 解释器将自动调用两个方法

  • __new__ 分配空间
  • __init__ 对象初始化

因此完成对 __new__ 方法的重写后,每次新建对象将会得到第一次创建对象时的引用但初始化方法每次还会被调用

只执行一次初始化工作

实现办法:定义一个类属性 init_flag 标记是否执行过初始化

复制代码
"""python单例"""


class MusicPlayer(object):

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

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

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

        # 1. 判断类属性是否是空对象
        if cls.instance is None:
            # 2. 调用父类的方法,为第一个对象分配空间
            cls.instance = super().__new__(cls)

        # 3. 返回类属性保存的对象引用
        return cls.instance

    def __init__(self):

        if not MusicPlayer.init_flag:
            print("初始化音乐播放器")

            MusicPlayer.init_flag = True
复制代码

 

posted on 2021-11-01 19:14  朴素贝叶斯  阅读(62)  评论(0编辑  收藏  举报

导航