最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2018年09月17日 10:25:36   投稿:mrr  
這篇文章主要介紹了深入理解Python中的 __new__ 和 __init__及區(qū)別介紹,這兩個方法的主要區(qū)別在于:__new__ 負責對象的創(chuàng)建而 __init__ 負責對象的初始化。具體內容詳情大家跟隨小編一起看看吧

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

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

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

Python中兩種類的定義方式

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

Python 2.x中老式類的定義:

class A: # -> inherits from type 
  pass

Python 2.x中新式類的定義:

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

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

下文中我們將通過測試 __new__ 和 __init__ 在各個case中的用法,來逐步剖析它們的功能和區(qū)別,并以此確實我們該如何使用它們。

分析不同的Case

在研究具體的實現(xiàn)之前,我們應該知道 __new__ 方法只接受 cls 作為它的第一個參數(shù),而 __init__ 一個參數(shù)是 self (__new__ 是一個類方法,而__init__ 是一個對象方法)。因為我們調用 __new__ 之前連實例都還沒有,因此那時根本沒有 self 的存在。__init__ 在 使用 __new__ 創(chuàng)建并返回一個實例之后調用,因此可將返回的實例通過self傳遞給它。

老式類中的__new__ 和 __init__

老式類中其實并沒有 __new__ 方法,因為 __init__ 就是它的構造方法(函數(shù))。因此如果我們有下面這段代碼:

class A:

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

A()

這個case中的 __new__ 方法將永遠不會執(zhí)行,因為它不是老式類的目標函數(shù)。

如果我們是重寫一個__init__ 方法:

class A:

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

A()

它將會輸出:

A.__init__ called

我們嘗試從 __init__ 方法中返回一個值:

class A:

  def __init__(self):
    return 29

A()

將會產生一個錯誤:

TypeError: __init__() should return None​

這意味著我們實例化一個老式類的對象時,不能控制它返回什么內容。

新式類中的 __new__ 和 __init__

新式類允許開發(fā)者根據(jù)他們的意圖來重寫 __new__ 和 __init__ 方法。__new__ (構造函數(shù))單獨地創(chuàng)建一個對象,而 __init__ (初始化函數(shù))負責初始化這個對象。

我們看一下下面這個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()

將會輸出:

A.__new__ called
A.__init__ called

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

class A(object):

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

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

輸出的內容如下:

A.__new__ called
None

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

顯然這個實例被認定None,如果我們沒有在構造函數(shù)中返回任何對象。

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

class A(object):

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

print A()
猜想會輸出如下的內容:

A.__new__ called
29

我們再看一下從 __init__ 中返回一個對象將會發(fā)生什么:

class A(object):

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

A()

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

TypeError: __init__ should return None

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

新式的類在靈活性上提供了更多的功能,允許我們在構造和初始化的級別做更多預處理和后處理的操作,讓我們可以在實例化時控制我們想要返回的內容。

考慮到這一點,我們嘗試一下在 __new__ 中返回一個其他類的對象。

首先,我們定義一個待用的類:

class Sample(object):

  def __str__(self):
    return "SAMPLE"

然后,再定義一個重寫 __new__ 方法的類:

class A(object):

def __new__(cls):
    return Sample()

也可以寫成下面這樣:

class A(object):

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

最后,我們調用A()來創(chuàng)建一個對象,并打印該對象:

print A()

這將會輸出:

SAMPLE

總結

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

相關文章

  • django 自定義過濾器(filter)處理較為復雜的變量方法

    django 自定義過濾器(filter)處理較為復雜的變量方法

    今天小編就為大家分享一篇django 自定義過濾器(filter)處理較為復雜的變量方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • Windows環(huán)境下創(chuàng)建并激活Python虛擬環(huán)境venv

    Windows環(huán)境下創(chuàng)建并激活Python虛擬環(huán)境venv

    Python虛擬環(huán)境venv是管理項目依賴的強大工具,通過創(chuàng)建、激活和使用虛擬環(huán)境,你可以輕松隔離和管理項目依賴,避免依賴沖突,提高開發(fā)效率和項目的可移植性,這篇文章主要介紹了Windows環(huán)境下創(chuàng)建并激活Python虛擬環(huán)境venv的相關資料,需要的朋友可以參考下
    2026-03-03
  • 淺談Python基礎之列表那些事兒

    淺談Python基礎之列表那些事兒

    這篇文章主要介紹了淺談Python基礎之列表那些事兒,文中有非常詳細的代碼示例,對正在學習Python基礎的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • 在Django的視圖中使用form對象的方法

    在Django的視圖中使用form對象的方法

    這篇文章主要介紹了在Django的視圖中使用form對象的方法,Django是Python豐富多彩的開發(fā)框架中最具有人氣的一個,需要的朋友可以參考下
    2015-07-07
  • python中使用print輸出中文的方法

    python中使用print輸出中文的方法

    今天小編就為大家分享一篇python中使用print輸出中文的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • python3+pyqt5+itchat微信定時發(fā)送消息的方法

    python3+pyqt5+itchat微信定時發(fā)送消息的方法

    今天小編就為大家分享一篇python3+pyqt5+itchat微信定時發(fā)送消息的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-02-02
  • Python數(shù)據(jù)集庫Vaex秒開100GB加數(shù)據(jù)

    Python數(shù)據(jù)集庫Vaex秒開100GB加數(shù)據(jù)

    這篇文章主要為大家介紹了Python數(shù)據(jù)集庫Vaex秒開100GB加數(shù)據(jù)實現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Python實現(xiàn)遍歷目錄的兩張方法總結

    Python實現(xiàn)遍歷目錄的兩張方法總結

    我們有時想直接查看文件夾里的所有文件,但使用正常的方法太麻煩了,于是本文開發(fā)出了兩個python程序,可以遍歷目錄,有需要的小伙伴可以參考下
    2024-02-02
  • python 調用HBase的簡單實例

    python 調用HBase的簡單實例

    下面小編就為大家?guī)硪黄猵ython 調用HBase的簡單實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • python爬取哈爾濱天氣信息

    python爬取哈爾濱天氣信息

    這篇文章主要為大家詳細介紹了python爬蟲抓取哈爾濱天氣信息,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07

最新評論

芦山县| 拜泉县| 常宁市| 太白县| 嘉义市| 九寨沟县| 大邑县| 望都县| 宝丰县| 尖扎县| 新巴尔虎右旗| 赫章县| 仲巴县| 镇原县| 东乌珠穆沁旗| 郑州市| 望谟县| 新邵县| 来凤县| 慈利县| 海原县| 吉安市| 和静县| 修水县| 突泉县| 赫章县| 双牌县| 临沭县| 城固县| 威海市| 浮山县| 孟州市| 察雅县| 阜阳市| 安乡县| 嘉黎县| 慈溪市| 嘉定区| 郁南县| 黄骅市| 西林县|