Python中__new__與__init__方法的區(qū)別詳解
在python2.x中,從object繼承得來的類稱為新式類(如class A(object))不從object繼承得來的類稱為經(jīng)典類(如class A())
新式類跟經(jīng)典類的差別主要是以下幾點(diǎn):
1. 新式類對(duì)象可以直接通過__class__屬性獲取自身類型:type
2. 繼承搜索的順序發(fā)生了改變,經(jīng)典類多繼承時(shí)屬性搜索順序: 先深入繼承樹左側(cè),再返回,開始找右側(cè)(即深度優(yōu)先搜索);新式類多繼承屬性搜索順序: 先水平搜索,然后再向上移動(dòng)
例子:
經(jīng)典類: 搜索順序是(D,B,A,C)
>>> class A: attr = 1 ... >>> class B(A): pass ... >>> class C(A): attr = 2 ... >>> class D(B,C): pass ... >>> x = D() >>> x.attr 1
新式類繼承搜索程序是寬度優(yōu)先
新式類:搜索順序是(D,B,C,A)
>>> class A(object): attr = 1 ... >>> class B(A): pass ... >>> class C(A): attr = 2 ... >>> class D(B,C): pass ... >>> x = D() >>> x.attr 2
3. 新式類增加了__slots__內(nèi)置屬性, 可以把實(shí)例屬性的種類鎖定到__slots__規(guī)定的范圍之中。
4. 新式類增加了__getattribute__方法
5.新式類內(nèi)置有__new__方法而經(jīng)典類沒有__new__方法而只有__init__方法
注意:Python 2.x中默認(rèn)都是經(jīng)典類,只有顯式繼承了object才是新式類
而Python 3.x中默認(rèn)都是新式類(也即object類默認(rèn)是所有類的祖先),不必顯式的繼承object(可以按照經(jīng)典類的定義方式寫一個(gè)經(jīng)典類并分別在python2.x和3.x版本中使用dir函數(shù)檢驗(yàn)下。
例如:
class A(): pass print(dir(A))
會(huì)發(fā)現(xiàn)在2.x下沒有__new__方法而3.x下有。
接下來說下__new__方法和__init__的區(qū)別:
在python中創(chuàng)建類的一個(gè)實(shí)例時(shí),如果該類具有__new__方法,會(huì)先調(diào)用__new__方法,__new__方法接受當(dāng)前正在實(shí)例化的類作為第一個(gè)參數(shù)(這個(gè)參數(shù)的類型是type,這個(gè)類型在c和python的交互編程中具有重要的角色,感興趣的可以搜下相關(guān)的資料),其返回值是本次創(chuàng)建產(chǎn)生的實(shí)例,也就是我們熟知的__init__方法中的第一個(gè)參數(shù)self。那么就會(huì)有一個(gè)問題,這個(gè)實(shí)例怎么得到?
注意到有__new__方法的都是object類的后代,因此如果我們自己想要改寫__new__方法(注意不改寫時(shí)在創(chuàng)建實(shí)例的時(shí)候使用的是父類的__new__方法,如果父類沒有則繼續(xù)上溯)可以通過調(diào)用object的__new__方法類得到這個(gè)實(shí)例(這實(shí)際上也和python中的默認(rèn)機(jī)制基本一致),如:
class display(object): def __init__(self, *args, **kwargs): print("init") def __new__(cls, *args, **kwargs): print("new") print(type(cls)) return object.__new__(cls, *args, **kwargs) a=display()
運(yùn)行上述代碼會(huì)得到如下輸出:
new <class 'type'> init
因此我們可以得到如下結(jié)論:
在實(shí)例創(chuàng)建過程中__new__方法先于__init__方法被調(diào)用,它的第一個(gè)參數(shù)類型為type。
如果不需要其它特殊的處理,可以使用object的__new__方法來得到創(chuàng)建的實(shí)例(也即self)。
于是我們可以發(fā)現(xiàn),實(shí)際上可以使用其它類的__new__方法類得到這個(gè)實(shí)例,只要那個(gè)類或其父類或祖先有__new__方法。
class another(object): def __new__(cls,*args,**kwargs): print("newano") return object.__new__(cls, *args, **kwargs) class display(object): def __init__(self, *args, **kwargs): print("init") def __new__(cls, *args, **kwargs): print("newdis") print(type(cls)) return another.__new__(cls, *args, **kwargs) a=display()
上面的輸出是:
newdis <class 'type'> newano init
所有我們發(fā)現(xiàn)__new__和__init__就像這么一個(gè)關(guān)系,__init__提供生產(chǎn)的原料self(但并不保證這個(gè)原料來源正宗,像上面那樣它用的是另一個(gè)不相關(guān)的類的__new__方法類得到這個(gè)實(shí)例),而__init__就用__new__給的原料來完善這個(gè)對(duì)象(盡管它不知道這些原料是不是正宗的)
- 詳解Python中的__init__和__new__
- python中的__init__ 、__new__、__call__小結(jié)
- Python中__init__和__new__的區(qū)別詳解
- 淺談python中的__init__、__new__和__call__方法
- 深入理解Python中的 __new__ 和 __init__及區(qū)別介紹
- Python函數(shù)__new__及__init__作用及區(qū)別解析
- Python中__new__和__init__的區(qū)別與聯(lián)系
- Python中class內(nèi)置方法__init__與__new__作用與區(qū)別解析
- python __init__與 __new__的區(qū)別
- 詳解Python中__new__和__init__的區(qū)別與聯(lián)系
- python中__new__和__init__的實(shí)現(xiàn)
相關(guān)文章
手把手帶你打造一個(gè)Pytest數(shù)據(jù)分離測(cè)試框架
數(shù)據(jù)分離測(cè)試框架是一種測(cè)試框架設(shè)計(jì)模式,旨在將測(cè)試數(shù)據(jù)與測(cè)試邏輯分離,以提高測(cè)試用例的可維護(hù)性、可讀性和復(fù)用性,本文就來實(shí)現(xiàn)一下,感興趣的可以了解一下2024-03-03Python的Django框架中模板碎片緩存簡(jiǎn)介
這篇文章主要介紹了Python的Django框架中模板碎片緩存,包括給cache標(biāo)簽傳遞參數(shù)等方法,需要的朋友可以參考下2015-07-07Python采用Django制作簡(jiǎn)易的知乎日?qǐng)?bào)API
這篇文章主要為大家詳細(xì)介紹了Python采用Django制作簡(jiǎn)易的知乎日?qǐng)?bào)API,感興趣的小伙伴們可以參考一下2016-08-08Python NumPy中的隨機(jī)數(shù)及ufuncs函數(shù)使用示例詳解
這篇文章主要介紹了Python NumPy中的隨機(jī)數(shù)及ufuncs函數(shù)使用,ufunc函數(shù)是NumPy中的一種通用函數(shù),它可以對(duì)數(shù)組中的每個(gè)元素進(jìn)行操作,而不需要使用循環(huán)語句,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-05-05python3+PyQt5圖形項(xiàng)的自定義和交互 python3實(shí)現(xiàn)page Designer應(yīng)用程序
這篇文章主要為大家詳細(xì)介紹了python3+PyQt5圖形項(xiàng)的自定義和交互,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04Python 列表 sort()函數(shù)使用實(shí)例詳解
這篇文章主要介紹了Python 列表 sort()函數(shù)使用詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07pytorch加載自定義網(wǎng)絡(luò)權(quán)重的實(shí)現(xiàn)
今天小編就為大家分享一篇pytorch加載自定義網(wǎng)絡(luò)權(quán)重的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-01-01一篇文章帶你了解python標(biāo)準(zhǔn)庫--datetime模塊
這篇文章主要為大家介紹了python中的datetime模塊,datetime模塊的接口則更直觀、更容易調(diào)用,想要了解datetime模塊的朋友可以參考一下2021-08-08