欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

深入理解Python中的 __new__ 和 __init__及區(qū)別介紹

系統(tǒng) 1746 0

本文的目的是討論P(yáng)ython中 __new__ 和 __ini___ 的用法。 __new__ 和 __init__ 的區(qū)別主要表現(xiàn)在:1. 它自身的區(qū)別;2. 及在Python中新式類(lèi)和老式類(lèi)的定義。

理解 __new__ 和 __init__ 的區(qū)別

這兩個(gè)方法的主要區(qū)別在于:__new__ 負(fù)責(zé)對(duì)象的創(chuàng)建而 __init__ 負(fù)責(zé)對(duì)象的初始化。在對(duì)象的實(shí)例化過(guò)程中,這兩個(gè)方法會(huì)有些細(xì)微的差別,表現(xiàn)于:如何工作,何時(shí)定義。

Python中兩種類(lèi)的定義方式

Python 2.x 中類(lèi)的定義分為新式定義和老式定義兩種。老式的類(lèi)出現(xiàn)在Python 3之前且定義時(shí)不繼承自'object' 基類(lèi),默認(rèn)是繼承自'type' :而新式類(lèi)在定義時(shí)顯示地繼承'object'類(lèi)。

Python 2.x中老式類(lèi)的定義:

            
class A: # -> inherits from type 
  pass
          

Python 2.x中新式類(lèi)的定義:

            
class A(object): # -> clearly inherits from object 
  pass
          

在Python 3.x中沒(méi)有新式類(lèi)和老式類(lèi)之分,它們都繼承自'object' 類(lèi)。因此可以不用顯示地指定其基類(lèi)。'object'基類(lèi)中擁有的方法和屬性可通用于所有的新式類(lèi)。

下文中我們將通過(guò)測(cè)試 __new__ 和 __init__ 在各個(gè)case中的用法,來(lái)逐步剖析它們的功能和區(qū)別,并以此確實(shí)我們?cè)撊绾问褂盟鼈儭?

分析不同的Case

在研究具體的實(shí)現(xiàn)之前,我們應(yīng)該知道 __new__ 方法只接受 cls 作為它的第一個(gè)參數(shù),而 __init__ 一個(gè)參數(shù)是 self (__new__ 是一個(gè)類(lèi)方法,而__init__ 是一個(gè)對(duì)象方法)。因?yàn)槲覀冋{(diào)用 __new__ 之前連實(shí)例都還沒(méi)有,因此那時(shí)根本沒(méi)有 self 的存在。__init__ 在 使用 __new__ 創(chuàng)建并返回一個(gè)實(shí)例之后調(diào)用,因此可將返回的實(shí)例通過(guò)self傳遞給它。

老式類(lèi)中的__new__ 和 __init__

老式類(lèi)中其實(shí)并沒(méi)有 __new__ 方法,因?yàn)?__init__ 就是它的構(gòu)造方法(函數(shù))。因此如果我們有下面這段代碼:

class A:

            
def __new__(cls):
    print "A.__new__ is called" # -> this is never called
          

A()

這個(gè)case中的 __new__ 方法將永遠(yuǎn)不會(huì)執(zhí)行,因?yàn)樗皇抢鲜筋?lèi)的目標(biāo)函數(shù)。

如果我們是重寫(xiě)一個(gè)__init__ 方法:

class A:

            
def __init__(self):
    print "A.__init__ called"
          

A()

它將會(huì)輸出:

A.__init__ called

我們嘗試從 __init__ 方法中返回一個(gè)值:

class A:

            
  def __init__(self):
    return 29
          

A()

將會(huì)產(chǎn)生一個(gè)錯(cuò)誤:

TypeError: __init__() should return None?

這意味著我們實(shí)例化一個(gè)老式類(lèi)的對(duì)象時(shí),不能控制它返回什么內(nèi)容。

新式類(lèi)中的 __new__ 和 __init__

新式類(lèi)允許開(kāi)發(fā)者根據(jù)他們的意圖來(lái)重寫(xiě) __new__ 和 __init__ 方法。__new__ (構(gòu)造函數(shù))單獨(dú)地創(chuàng)建一個(gè)對(duì)象,而 __init__ (初始化函數(shù))負(fù)責(zé)初始化這個(gè)對(duì)象。

我們看一下下面這個(gè)case的執(zhí)行順序:

            
class A(object): # -> don t forget the object specified as base

  def __new__(cls):
    print "A.__new__ called"
    return super(A, cls).__new__(cls)

  def __init__(self):
    print "A.__init__ called"
          

A()

將會(huì)輸出:

A.__new__ called
A.__init__ called

你可能想要問(wèn) __init__ 和 __new__ 是在哪里被調(diào)用的,我能告訴你的是: __new__ 是在我們調(diào)用類(lèi)名進(jìn)行實(shí)例化時(shí)自動(dòng)調(diào)用的,__init__ 是在這個(gè)類(lèi)的每一次實(shí)例化對(duì)象之后調(diào)用的,__new__ 方法創(chuàng)建一個(gè)實(shí)例之后返回這個(gè)實(shí)例對(duì)象并傳遞給 __init__ 方法的 self 參數(shù)。因此,即使你將創(chuàng)建的實(shí)例對(duì)象保存成一個(gè)全局或靜態(tài)的變量,并且每次調(diào)用__new__ 方法時(shí)都返回這個(gè)對(duì)象,__init__ 方法依然每次都會(huì)被調(diào)用。這意味著如果我們?cè)?__new__ 中省略調(diào)用基類(lèi)的super(A, cls).__new__(cls) 代碼,__init__ 方法將不會(huì)被執(zhí)行。我們一起看一下這個(gè)case的代碼:

class A(object):

            
  def __new__(cls):
    print "A.__new__ called"

  def __init__(self):
    print "A.__init__ called" # -> is actually never called
print A()
          

輸出的內(nèi)容如下:

A.__new__ called
None

Obviously the instantiation is evaluated to None since we don't return anything from the constructor.

顯然這個(gè)實(shí)例被認(rèn)定None,如果我們沒(méi)有在構(gòu)造函數(shù)中返回任何對(duì)象。

想像一下,如果我們從 __new__ 中返回一些其他東西(對(duì)象)將會(huì)發(fā)生什么,如下面這樣:

class A(object):

            
 def __new__(cls):
    print "A.__new__ called"
    return 29
          

print A()
猜想會(huì)輸出如下的內(nèi)容:

A.__new__ called
29

我們?cè)倏匆幌聫?__init__ 中返回一個(gè)對(duì)象將會(huì)發(fā)生什么:

class A(object):

            
 def __init__(self):
    print "A.__init__ called" 
      return 33 # -> TypeError: __init__ should return None
          

A()

這將會(huì)出現(xiàn)警告:

TypeError: __init__ should return None

在調(diào)用 __init__ 時(shí)會(huì)出現(xiàn)一個(gè)TypeError的異常 :__init__() should return None, not ‘int' 。這主要是因?yàn)?__init__ 的作用只是刷新和更改剛創(chuàng)建的這個(gè)實(shí)例對(duì)象的狀態(tài)。

新式的類(lèi)在靈活性上提供了更多的功能,允許我們?cè)跇?gòu)造和初始化的級(jí)別做更多預(yù)處理和后處理的操作,讓我們可以在實(shí)例化時(shí)控制我們想要返回的內(nèi)容。

考慮到這一點(diǎn),我們嘗試一下在 __new__ 中返回一個(gè)其他類(lèi)的對(duì)象。

首先,我們定義一個(gè)待用的類(lèi):

class Sample(object):

            
  def __str__(self):
    return "SAMPLE"
          

然后,再定義一個(gè)重寫(xiě) __new__ 方法的類(lèi):

class A(object):

            
def __new__(cls):
    return Sample()
          

也可以寫(xiě)成下面這樣:

class A(object):

            
 def __new__(cls):
    return super(A, cls).__new__(Sample)
          

最后,我們調(diào)用A()來(lái)創(chuàng)建一個(gè)對(duì)象,并打印該對(duì)象:

print A()

這將會(huì)輸出:

SAMPLE

總結(jié)

以上所述是小編給大家介紹的Python中的 __new__ 和 __init__及區(qū)別介紹,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

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

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 中文字幕在线观看 | 911色_911色sss主站色播 | 91文字幕巨乱亚洲香蕉 | 亚洲精品不卡久久久久久 | jizzjizzjizz欧美 | 欧美精品免费在线 | 天天操天天干天天 | 天堂在线资源av | 欧美日韩国产手机在线观看视频 | 骚视频在线观看 | 国产女人与拘做受视频 | 日韩专区在线播放 | 成人亚洲一区 | 久久久久久久久久免观看 | 国产精品久久久久无码av | 色综合久久天天综合绕观看 | 人人干人人模 | 午夜影院在线观看视频 | 国产成人精品免费 | 久久久久久久一区二区三区 | 亚洲欧美中日韩中文字幕 | 日韩黄色一级视频 | 波多野结衣全部系列在线观看 | 亚州精品天堂中文字幕 | 很黄很色的小视频在线网站 | 亚洲欧美在线观看 | 成人一级大片 | 奇米4色| 色网站综合| 香港一级毛片在线播放 | 精品视频久久久久 | 欧美激情久久久久久久久 | 性欧美一级毛片在线播放 | 丁香婷婷亚洲六月综合色 | 老版亮剑50集免费观看 | 中文字幕亚洲一区二区三区 | 国产激情偷乱视频一区二区三区 | 99久久精品免费 | 国产嫩草影院在线观看 | 婷婷尹人香蕉久久天堂 | 亚洲成人午夜在线 |