提到构造器,大家都会想到 __init__,那么__new__是什么?也是构造器。
init 构造器
都很熟悉了,直接上代码
class MyClass(object): def __init__(self): pass def m1(self): print(3) mc = MyClass() mc.m1() # 3
是不是很简单
别急,请跟着我的思路,方法m1的参数有个self,这个self就是实例,在调用m1之前这个实例肯定已经产生了;但是init的参数也有个self,在调用init之前,我们并没有实例化,那这个self从何而来呢?new生成的。
new 构造器
1. new 和 init 一样都是类的构造器
2. new在init之前执行,即使没有显示定义
3. new 必须有返回对象,这个对象就是该类的实例,或者父类的实例(该类继承了一个类),并且是new出来的实例,这个实例的就是self,也就是该类的实例化对象。
4. new生成的self传给init,如果没有正确返回实例,init将不会执行。
5. new可以自定义
6. new是类方法,需要显示的传入类cls作为第一个参数,至少要有这个参数
7. 新式类中才有new
8. new和init共用参数,也就是说二者参数形式要一致
几个例子来验证上面8条。
代码1
class A(object): def __init__(self,a): print "init" self.a=a def __new__(cls,*args, **kwargs): print "new %s"%cls print('args:', args) return object.__new__(cls, *args, **kwargs) # 返回当前类的实例 aa=A(3) # new <class '__main__.A'> # ('args:', (3,)) # init print(aa) # <__main__.A object at 0x026FC4B0> print(aa.a) # 3 self.a
1. 新式类,经典类我试了,不行,new没有运行,但不会报错
2. new 比 init 先执行
3. new 和 init 共用了参数3
4. new 返回了当前类的实例,new出来的
代码2
class inch(float): def __new__(cls, arg=0.0): # cls 相当于 self print(1) return float.__new__(cls, arg * 0.0254) def __init__(self, aa): print('aa:', aa) print(2) a = inch(12) # new 和 init 公用了参数12 # 1 # ('aa:', 12) # 2 print(a) # 返回的实例就是new的return,父类的实例 float(12*0.0254) # 0.3048 =12*0.0254
1. 该类继承了float类
2. new 返回了父类float的实例
3. 该类实例化后其实是new 返回的实例,也就是float(12*0.0254)
代码3
class inch2(float): def __new__(cls, arg=0.0): # cls 相当于 self print(11) return float.__new__(cls, arg)*0.0254 # 返回了父类的实例*0.0254 def __init__(self,aa): print(22) # 这句没有被执行,因为new没有正确返回父类的实例 a = inch2(12) # 11 print(a) # 0.3048 =12*0.0254
new没有正确返回父类的实例,导致init没有被执行。