- 1. __new__和__init__方法的区别
- 2. 单例模式
- 2.1 什么是单例
- 2.2 单例模式
我们先看一个例子:
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 单例模式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
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)