__new__() 是新式類中才有的方法,它執行在構造方法建立實例以前。能夠這麼理解,在 Python 中類中的構造方法 __init__() 負責將類實例化,而在 __init__() 啓動以前,__new__() 決定是否要使用該 __init__() 方法(由於__new__() 能夠調用其餘類的構造方法或者直接返回別的對象來做爲本類的實例)。html
若是將類比喻成工廠,那麼__init__()方法則是該工廠的生產工人,__init__()方法接受的初始化參數則是生產所需的原料,__init__()方法會按照方法中的語句負責將原料加工成實例以供工廠出貨。而__new__()則是生產部經理,__new__()方法既能夠將原料提供給該生產部門的工人,也能夠將原料提供給其餘的外來單位,由於這名經理能夠借該工廠的名義向其餘單位出讓生產原料(假公濟私)。python
__new__() 方法的特性:安全
class MyClass(object): def __init__(self, *args, **kwargs): ... # 實例化 myclass = MyClass(*args, **kwargs)
正如以上所示,一個類能夠有多個位置參數和多個命名參數,而在實例化開始以後,在調用 __init__() 方法以前,Python 首先調用 __new__() 方法:框架
def __new__(cls, *args, **kwargs): ...
第一個參數cls是當前正在實例化的類。spa
例如,若是當前類是直接繼承自 object,那當前類的 __new__() 方法返回的對象應該爲:設計
def __new__(cls, *args, **kwargs): ... return object.__new__(cls)
注意:htm
事實上若是(新式)類中沒有重寫__new__()方法,即在定義新式類時沒有從新定義__new__()時,Python默認會調用該類的直接父類的__new__()方法來構造該類的實例,若是該類的父類也沒有重寫__new__(),那麼將一直按此規矩追溯直至object的__new__()方法,由於object是全部新式類的基類。 對象
若是新式類中重寫了__new__()方法,那麼你能夠選擇任意一個該新式類的全部前代類和後代類((只能是新式類,經典類中沒有__new__()方法)的__new__()方法來製造實例),只要它們不會形成遞歸死循環。具體看如下代碼解釋:blog
class Foo(object): def __init__(self, *args, **kwargs): ... def __new__(cls, *args, **kwargs): return object.__new__(cls, *args, **kwargs) # 以上return等同於 # return object.__new__(Foo, *args, **kwargs) # return Stranger.__new__(cls, *args, **kwargs) # return Child.__new__(cls, *args, **kwargs) class Child(Foo): def __new__(cls, *args, **kwargs): return object.__new__(cls, *args, **kwargs) # 若是Child中沒有定義__new__()方法,那麼會自動調用其父類的__new__()方法來製造實例,即 Foo.__new__(cls, *args, **kwargs)。 # 在任何新式類的__new__()方法,不能調用自身的__new__()來製造實例,由於這會形成死循環。所以必須避免相似如下的寫法: # 在Foo中避免:return Foo.__new__(cls, *args, **kwargs)或return cls.__new__(cls, *args, **kwargs)。Child同理。 # 使用object或者沒有血緣關係的新式類的__new__()是安全的,可是若是是在有繼承關係的兩個類之間,應避免互調形成死循環, # 例如:(Foo)return Child.__new__(cls), (Child)return Foo.__new__(cls)。 class Stranger(object): ... # 在製造Stranger實例時,會自動調用 object.__new__(cls)
注意:若是__new__()沒有返回cls(即當前類)的實例,那麼當前類的__init__()方法是不會被調用的。若是__new__()返回其餘類(新式類或經典類都可)的實例,那麼只會調用被返回的那個類的構造方法。繼承
class Foo(object): def __init__(self, *args, **kwargs): ... def __new__(cls, *args, **kwargs): return object.__new__(Stranger, *args, **kwargs) class Stranger(object): ... foo = Foo() print type(foo) # 打印的結果顯示foo實際上是Stranger類的實例。 # 所以能夠這麼描述__new__()和__init__()的區別,在新式類中__new__()纔是真正的實例化方法, # 爲類提供外殼製造出實例框架,而後調用該框架內的構造方法__init__()使其豐滿。 # 若是以建房子作比喻,__new__()方法負責開發地皮,打下地基,並將原料存放在工地。而__init__()方法 # 負責從工地取材料建造出地皮開發招標書中規定的大樓,__init__()負責大樓的細節設計,建造,裝修使其可交付給客戶。