python的

python的,第1张

python的

文章目录
  • 1. __new__和__init__方法的区别
  • 2. 单例模式
    • 2.1 什么是单例
    • 2.2 单例模式

1. __new__和__init__方法的区别

我们先看一个例子:

class Idol(object):

    def __new__(cls, name, age):
        print('__new__ called')
        return super(Idol, cls).__new__(cls)

    def __init__(self, name, age):
        print('__init__ called')
        self.name = name
        self.age = age

    def __str__(self):
        return 'Idol: %s-%s' % (self.name, self.age)


if __name__ == '__main__':
    name = Idol('kobe', 24)
    print(name)

实例化一个对象,输出结果:

__new__ called
__init__ called
Idol: kobe-24

通过这段代码我们看到,实例化一个类的时候,new 方法的调用发生在 init 之前。实例化一个类的语句为 p = Idol(name, age),其具体的执行逻辑如下:

  • 首先执行 Idol 类的 new 方法,这个 new 方法会返回 Idol 类的一个实例(通常情况下是使用 super(Idol, cls).new(cls)这样的方式);
  • 然后利用这个实例来调用类的 init 方法,上一步里面 new 产生的实例也就是 init 里面的的 self。

由此,init 和 new 的区别在于:

  • new 通常用于控制生成一个新实例的过程。它是类级别的方法。
  • new 至少要有一个参数 cls,代表要实例化的类,该参数在实例化时由 Python 解释器自动提供;
  • new 必须要有返回值,返回实例化出来的实例;
  • init 通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性,做一些额外的 *** 作,发生在类实例被创建完以后。它是实例级别的方法。
2. 单例模式 2.1 什么是单例

确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类。

例如,我们电脑的回收站就是单例模式,在整个 *** 作系统中,回收站只能有一个实例,整个系统都使用这个唯一的实例,而且回收站自行提供自己的实例。

2.2 单例模式
class Singleton(object):
    __instance = None

    def __new__(cls, num, name):
        # 先判断是否有这个类的实例,没有就实例化一个并赋值给引用,有就直接返回该实例,以此保证单例
        if not cls.__instance:
            cls.__instance = super(Singleton, cls).__new__(cls)
        return cls.__instance

    def __init__(self, num, name):
        self.num = num
        self.name = name


if __name__ == '__main__':
    a = Singleton(24, "kobe")
    print(id(a))
    print(a.num)

    b = Singleton(30, "curry")
    print(id(b))
    print(b.num)

输出:

140392531769904
24
140392531769904
30

由输出我们看到,上面的代码实现了 Singleton 类的单例;同时我们也发现,单例类的 __new__ 方法只能调用一次,但 __init__ 方法会调用多次,我们可以在 __init__ 方法中修改属性。

我们也可以实现只执行一次 __init__ 方法的单例,通过在 __init__ 方法中增加一个标志位来实现,如下:

class Singleton(object):
    __instance = None
    __first_init = False

    def __new__(cls, num, name):
        # 先判断是否有这个类的实例,没有就实例化一个并赋值给引用,有就直接返回该实例,以此保证单例
        if not cls.__instance:
            cls.__instance = super(Singleton, cls).__new__(cls)
        return cls.__instance

    def __init__(self, num, name):
        if not self.__first_init:
            self.num = num
            self.name = name
            self.__first_init = True


if __name__ == '__main__':
    a = Singleton(24, "kobe")
    print(id(a))
    print(a.num)

    b = Singleton(30, "curry")
    print(id(b))
    print(b.num)

输出:

139650736351792
24
139650736351792
24

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5689224.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存