python中例項化 Python中的 new

2021-10-11 05:40:04 字數 3137 閱讀 3831

__new__()是在新式類中新出現的方法,它作用在構造方法建造例項之前,可以這麼理解,在python 中 存在於類裡面的構造方法__init__()負責將類的例項化,而在__init__()啟動之前,__new__()決定是否 要使用該__init__()方法,因為__new__()可以呼叫其他類的構造方法或者直接返回別的物件來作為本類 的例項。

如果將模擬喻為工廠,那麼__init__()方法則是該工廠的生產工人,__init__()方法接受的初始化參 數則是生產所需原料,__init__()方法會按照方法中的語句負責將原料加工成例項以供工廠出貨。而 __new__()則是生產部經理,__new__()方法可以決定是否將原料提供給該生產部工人,同時它還決定著出 貨產品是否為該生產部的產品,因為這名經理可以借該工廠的名義向客戶**完全不是該工廠的產品。

__new__()方法的特性:

__new__()方法是在類準備將自身例項化時呼叫。

__new__()方法始終都是類的靜態方法,即使沒有被加上靜態方法裝飾器。

類的例項化和它的構造方法通常都是這個樣子:

class myclass(object):

def __init__(self, *args, **kwargs):

# 例項化

myclass = myclass(*args, **kwargs)

正如以上所示,乙個類可以有多個位置引數和多個命名引數,而在例項化開始之後,在呼叫 __init__()方法之前,python首先呼叫__new__()方法:

def __new__(cls, *args, **kwargs):

第乙個引數cls是當前正在例項化的類。

如果要得到當前類的例項,應當在當前類中的__new__()方法語句中呼叫當前類的父類 的__new__()方法。

例如,如果當前類是直接繼承自object,那當前類的__new__()方法返回的物件應該為:

def __new__(cls, *args, **kwargs):

return object.__new__(cls)

注意:事實上如果(新式)類中沒有重寫__new__()方法,即在定義新式類時沒有重新定義__new__()時 ,python預設是呼叫該類的直接父類的__new__()方法來構造該類的例項,如果該類的父類也沒有重寫 __new__(),那麼將一直按此規矩追溯至object的__new__()方法,因為object是所有新式類的基類。

而如果新式類中重寫了__new__()方法,那麼你可以自由選擇任意乙個的其他的新式類(必定要是 新式類,只有新式類必定都有__new__(),因為所有新式類都是object的後代,而經典類則沒有__new__() 方法)的__new__()方法來製造例項,包括這個新式類的所有前代類和後代類,只要它們不會造成遞迴死 迴圈。具體看以下**解釋:

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(cls指代當前類)的例項,然後該類的 __init__()方法作為構造方法會接收這個例項(即self)作為自己的第乙個引數,然後依次傳入__new__ ()方法中接收的位置引數和命名引數。

注意:如果__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__()和__ini__()的區別,在新式類中__new__()才是真正的例項化方法,為類

提供外殼製造出例項框架,然後呼叫該框架內的構造方法__init__()使其豐滿。

# 如果以建房子做比喻,__new__()方法負責開發地皮,打下地基,並將原料存放在工地。而__init__()

方法負責從工地取材料建造出地皮開發招標書中規定的大樓,__init__()負責大樓的細節設計,建造,裝

修使其可交付給客戶

python中初始化例項屬性

雖然我們可以自由地給乙個例項繫結各種屬性,但是,現實世界中,一種型別的例項應該擁有相同名字的屬性。例如,person類應該在建立的時候就擁有 name gender 和 birth 屬性,怎麼辦?在定義 person 類時,可以為person類新增乙個特殊的 init 方法,當建立例項時,init ...

python反射例項化 python反射

定義 通過字串的形式去操作物件 類,例項物件,模組中的物件 中的成員 增刪改查 叫反射。一 類例項物件class foo tests test def init self,name,age self.name name self.age age def show self return s s se...

python中var是什麼變數 Python 變數

1.python的變數是什麼 變數是用來儲存電腦程式中的資訊,唯一的目的是將資料儲存在記憶體中。2.python變數的組成 變數由字母 數字 下劃線組成 變數的第一位不能是數字,可以是字母或下劃線 python中的關鍵字不能作為變數。python中的關鍵字 and as assert break c...