這兩個方法是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方法
上面這段代碼是說構造函數有返回值,但不是當前類的實例對象,所以也不能調用初始化方法。