亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Python中__new__與__init__方法的區別詳解

系統 1758 0

在python2.x中,從object繼承得來的類稱為新式類(如class A(object))不從object繼承得來的類稱為經典類(如class A())

新式類跟經典類的差別主要是以下幾點:

  1. 新式類對象可以直接通過__class__屬性獲取自身類型:type

  2. 繼承搜索的順序發生了改變,經典類多繼承時屬性搜索順序: 先深入繼承樹左側,再返回,開始找右側(即深度優先搜索);新式類多繼承屬性搜索順序: 先水平搜索,然后再向上移動

例子:

經典類: 搜索順序是(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

          

新式類繼承搜索程序是寬度優先

新式類:搜索順序是(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__內置屬性, 可以把實例屬性的種類鎖定到__slots__規定的范圍之中。

  4. 新式類增加了__getattribute__方法

  5.新式類內置有__new__方法而經典類沒有__new__方法而只有__init__方法

注意:Python 2.x中默認都是經典類,只有顯式繼承了object才是新式類

  ?? 而Python 3.x中默認都是新式類(也即object類默認是所有類的祖先),不必顯式的繼承object(可以按照經典類的定義方式寫一個經典類并分別在python2.x和3.x版本中使用dir函數檢驗下。

例如:

            
class A():

      pass

    print(dir(A))


          

會發現在2.x下沒有__new__方法而3.x下有。

接下來說下__new__方法和__init__的區別:

在python中創建類的一個實例時,如果該類具有__new__方法,會先調用__new__方法,__new__方法接受當前正在實例化的類作為第一個參數(這個參數的類型是type,這個類型在c和python的交互編程中具有重要的角色,感興趣的可以搜下相關的資料),其返回值是本次創建產生的實例,也就是我們熟知的__init__方法中的第一個參數self。那么就會有一個問題,這個實例怎么得到?

注意到有__new__方法的都是object類的后代,因此如果我們自己想要改寫__new__方法(注意不改寫時在創建實例的時候使用的是父類的__new__方法,如果父類沒有則繼續上溯)可以通過調用object的__new__方法類得到這個實例(這實際上也和python中的默認機制基本一致),如:

            
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()

          

運行上述代碼會得到如下輸出:

            
new


            
              

init


            
          

因此我們可以得到如下結論:

在實例創建過程中__new__方法先于__init__方法被調用,它的第一個參數類型為type。

如果不需要其它特殊的處理,可以使用object的__new__方法來得到創建的實例(也即self)。

于是我們可以發現,實際上可以使用其它類的__new__方法類得到這個實例,只要那個類或其父類或祖先有__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

            
              
newano
init

            
          

所有我們發現__new__和__init__就像這么一個關系,__init__提供生產的原料self(但并不保證這個原料來源正宗,像上面那樣它用的是另一個不相關的類的__new__方法類得到這個實例),而__init__就用__new__給的原料來完善這個對象(盡管它不知道這些原料是不是正宗的)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 91精品国产欧美一区二区 | 午夜视频网址 | 中文字幕51精品乱码在线 | 精品国产线拍大陆久久尤物 | 99国产精品免费视频观看 | 亚洲国产日韩综合久久精品 | 狠狠婷| 91久久免费视频 | 香蕉成人在线 | 久久天天躁狠狠躁夜夜不卡 | 天天插天天操 | 人成午夜视频 | 91免费福利视频 | 97久久国语露脸精品对白 | 久久精品亚洲欧美va | 亚洲日本欧美日韩高观看 | 国产在线精品成人一区二区三区 | 尹人综合| 久久亚洲不卡一区二区 | 香蕉黄色网 | 超激情碰碰碰啪在线视频 | www色综合| 欧美乱淫视频 | 欧美成人怡红院在线观看 | 色中文在线 | 美日韩在线视频 | 国产精品欧美亚洲韩国日本不卡 | 福利在线视频观看 | 美国毛片一级视频在线aa | 亚洲成在人天堂一区二区 | 四虎永久精品免费网址大全 | 天天看天天射天天碰 | 久久久噜久噜久久综合 | 亚洲精品一级一区二区三区 | 亚洲高清一区二区三区四区 | 国产福利在线观看 | 国内在线播放 | 久久草在线视频 | 中文字幕精品一区二区日本大胸 | 一级淫片免费看 | 夜夜爽天天狠狠九月婷婷 |