概括:簡言之,_new_作用於_init_之前。前者可以決定是否調用後者,或者說可以決定調用哪個類的_init_方法。
解釋一:首先要知道在面向對象編程中,實例化基本遵循創建實例對象、初始化實例對象、最後返回實例對象這麼一個過程。Python 中的 _new_ 方法負責創建一個實例對象,_init_ 方法負責將該實例對象進行初始化;
解釋二:有人說如果將類比喻爲工廠,那麼_init_方法則是該工廠的生產工人,_init_方法接受的初始化參數則是生產所需原料,_init_方法會按照方法中的語句負責將原料加工成實例以供工廠出貨。而_new_則是生產部經理,_new_方法可以決定是否將原料提供給該生產部工人,同時它還決定着出貨產品是否爲該生產部的產品,因爲這名經理可以借該工廠的名義向客戶出售完全不是該工廠的產品。
_new_() 方法的特性:
- new() 方法是在類準備將自身實例化時調用;
-new() 方法始終都是類的靜態方法,即使沒有被加上靜態方法裝飾器 ; - 繼承自object的新式類纔有new;
new至少要有一個參數cls,代表要實例化的類,此參數在實例化時由Python解釋器自動提供;
-new必須要有返回值,返回實例化出來的實例,這點在自己實現new時要特別注意,可以return父類new出來的實例,或直接是object的new出來的實例。
如圖(1)與圖(2)等價:
_init_有一個參數self,就是這個_new_返回的實例,_init_在_new_的基礎上可以完成一些其它初始化的動作,_init_不需要返回值;
若new沒有正確返回當前類cls的實例,那當前類的init是不會被調用的,即使是父類的實例也不行。如下圖(def new(cls, *args, **kwargs)…: 第一個參數cls是當前正在實例化的類):
針對上圖,可知B是A的實例,但是沒有默認執行A的init函數,此時若顯示調用b的init(),會執行對應實例的init(),如下:
若new返回當前類cls的實例,則該類的init方法會被調用,且不避顯示調用,如下圖:
類的實例化和它的構造方法通常都是這個樣子(附:當不確定參數個數時,可用*args,**kwargs—前者是tuple,後者是dict):