这两个方法是python类中的基本方法,常常会在一些面试中问到。即使没有要面试之类的,学习一下其内部的原理和使用也是有必要的。python
一点小插曲:面试
__new__方法在继承自object的新式类中才有,说到这里,提一下新式类与经典类:函数
1 def __init__(self, *args, **kwargs): 2 pass 3 4 def __new__(cls, *args, **kwargs): 5 return object.__new__(cls, *args, **kwargs)
上面给出了初始化方法和构造函数,能够看到初始化方法没有返回值,而构造函数有返回值。学习
首先,在建立一个类的实例时,先调用构造方法(new),他接受当前正在实例化的类做为第一参数(cls),而后返回建立产生的实例,给__init__方法的第一参数self,让其进行初始值的设置。
咱们在初学时常常会见到init方法,可是不多见到new方法,这里解释一下,new方法常常不被重写,python中默认调用了父类的new,若是父类没有就继续上溯,直到object的new方法。(既然说是重写了,那么就必定在他的祖先类中有这个方法,最根本的就是object类,他是全部新式类的基类)spa
文字也许看的有点懵,那就举个例子:code
1 class A(object): 2 """docstring for A""" 3 def __init__(self, *args, **kwargs): 4 print("init ",self.__class__) 5 6 def __new__(cls, *args,**kwargs): 7 print("new ",cls) 8 return object.__new__(cls, *args,**kwargs) 9 10 a = A()
结果输出:
new <class '__main__.A'>
init <class '__main__.A'>对象
上面的类中定义了init和new,在建立实例对象a时,代码执行只是通过了init的函数定义部分,把这个函数名存在记忆当中,须要用时再调用。而后到了new方法时,接受当前这个类给第一参数cls,来建立对象。建立好对象以后,这个对象的属性方法还什么都没有,如今就返回这个对象(也就是init中的self),来给init来初始化一些内容。若是构造函数并无返回这个类的对象,那么init方法也就不会被调用。这也符合了上面的输出结果,先输出的new方法的内容,后执行的init方法中的输出。blog
没有返回这个类的对象能够是根本就没有返回值,也多是返回的对象并非当前的类的对象,下面会对应举两个例子:继承
上面这张截图中,我把上面代码的new方法返回删掉了,如今就只调用的new方法,而没有到init方法内部去。如今这种状况就是new没有返回对象,init方法的第一参数self就没有接收到要初始化的对象,所以并不执行。string
1 class A(object): 2 """docstring for A""" 3 pass 4 5 class B(A): 6 """docstring for B"Af __init__(self, arg): """ 7 def __init__(self): 8 print("init ",self.__class__) 9 10 def __new__(cls): 11 print("new ",cls) 12 return object.__new__(A) # 返回的是A的对象,并非当前类中的实例对象,因此不能调用init方法
上面这段代码是说构造函数有返回值,但不是当前类的实例对象,所以也不能调用初始化方法。