面向對象—的__new__()方法詳解

[Python] Python 之 __new__() 方法與實例化

__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__()負責大樓的細節設計,建造,裝修使其可交付給客戶。

轉載于:https://www.cnblogs.com/TF511/p/10039159.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/450517.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/450517.shtml
英文地址,請注明出處:http://en.pswp.cn/news/450517.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

git使用回滾,清除暫緩區,解決沖突(持續更新)

1、git restore --staged <文件> 清除暫緩區文件名 2、git reset --hard <版本號> 回滾到上一版本 如看PHPstrom如何操作請參考https://blog.csdn.net/qq_35774849/article/details/107312658 3、解決沖突 &#xff08;1&#xff09;使用默認的解決沖突 打開…

14.安全

1.基本概念 安全問題的產生&#xff1a; 互聯網作為商業交易的工具快速發展&#xff0c;越來越多的公司提供網絡交易服務。很多商業活動在網上進行當前&#xff0c;成千上萬的網民在網上進行各種活動的同時&#xff0c;也在網上傳遞其個人信息每天在網上發生各種各樣的商業活動…

C語言enum關鍵字

很多初學者對枚舉(enum)感到迷惑&#xff0c;或者認為沒什么用&#xff0c;其實枚舉(enum)是個很有用的數據類型。一、枚舉類型的使用方法 一般的定義方式如下&#xff1a;enum enum_type_name{ENUM_CONST_1,ENUM_CONST_2,...ENUM_CONST_n} enum_variable_name;注意&#xff1a…

Dubbo 需求、架構、使用Demo

只是整理下方便自己記錄 內容全部來自官網&#xff1a;http://dubbo.io/books/dubbo-user-book/preface/usage.html 一、需求 在大規模服務化之前&#xff0c;應用可能只是通過 RMI 或 Hessian 等工具&#xff0c;簡單的暴露和引用遠程服務&#xff0c;通過配置服務的URL地址進…

Ubuntu安裝之python開發

Ubuntu安裝之python開發 什么&#xff1f;&#xff1f;Ubuntu(烏班圖)開發&#xff1f;不會用&#xff1f;&#xff1f;怎么進行python開發&#xff1f;&#xff1f;&#xff1f; 烏班圖操作系統下載地址&#xff1a;http://releases.ubuntu.com/18.04/ubuntu-18.04.1-desktop-…

vimdiff和vim-fugitive安裝,使用教程

1、vimdiff的安裝 在終端執行 git config --global merge.tool vimdiff git config --global merge.conflictstyle diff3 git config --global mergetool.prompt false git config --global diff.tool vimdiff git config --global difftool.prompt false git config --…

在 PowerPoint 2016 中嵌入網頁

之前在智圖這個網站上做了一張地圖&#xff0c;在嵌入 PPT 里面的時候碰到了一些問題&#xff0c;現在把找到的解決方法寫下來。 PPT 里面自帶的 WebBrowser 控件可以實現網頁瀏覽的功能。在“開發工具”選項卡下的“其他控件”中找到“Microsoft Web Browser”&#xff0c;在畫…

js 正則表達式 整合

正則表達式:斷言 取字符串區間: /(?<[" star "]).*(?[" end "])/// 簡單封裝 Vue.prototype.strMatch (str,star,end) > { let regs new RegExp("(?<[" star "]).*(?[" end "])"); let req str…

dubbo 注冊中心zookeeper 手冊

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 zookeeper 注冊中心 Zookeeper 是 Apacahe Hadoop 的子項目&#xff0c;是一個樹型的目錄服務&#xff0c;支持變更推送&#xff0c;適…

數組 深入詳解

再論C語言數組 C語言處理數組的方式是它廣受歡迎的原因之一。C語言對數組的處理是非常有效的&#xff0c;其原因有以下三點&#xff1a;第一&#xff0c;除少數翻譯器出于謹慎會作一些繁瑣的規定外&#xff0c;C語言的數組下標是在一個很低的層次上處理的。但這個優點也有一個反…

oracle ins-30131錯誤

打開cmd 但是在我的環境沒效果&#xff0c;而我已知臨時目錄沒有問題。那么在命令行進入安裝軟件目錄&#xff0c;通過命令行啟動安裝程序&#xff0c;設置 ignorePrereq 檢查&#xff0c;此時數據庫軟件可以啟動安裝&#xff0c;是否會出現錯誤&#xff0c;就看忽略的檢查是否…

iOS開發UI篇—簡單介紹靜態單元格的使用

一、實現效果與說明 說明&#xff1a;觀察上面的展示效果&#xff0c;可以發現整個界面是由一個tableview來展示的&#xff0c;上面的數據都是固定的&#xff0c;且幾乎不會改變。 要完成上面的效果&#xff0c;有幾種方法&#xff1a; &#xff08;1&#xff09;可以直接利用代…

展示內容

今天課上展示了軟件 評價為過于簡單 還需另尋他法轉載于:https://www.cnblogs.com/wmqlzm/p/10041683.html

dubbo ,dubbo-provider、dubbo-consumer 配置參數說明

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 dubbo:consumer 服務消費者缺省值配置。配置類&#xff1a; com.alibaba.dubbo.config.ConsumerConfig 。同時該標簽為 <dubbo:refer…

laraval使用sqlite設置從多少開始遞增

DB::statement( "UPDATE SQLITE_SEQUENCE SET seq 起始值 WHERE name 表名" ); sqlite3默認就是1。 新建了含PRIMARY KEY AUTOINCREMENT 主鍵自增表(如 test1)后&#xff0c;會自動在sqlite_sequence表插入或更新一條信息&#xff0c;其中保存了相關主鍵的最大值&…

指針深入探討

C語言變量的內存實質 一、先來理解C語言中變量的實質 要理解C指針&#xff0c;我認為一定要理解C中“變量”的存儲實質&#xff0c;所以我就從“變量”這個東西開始講起吧&#xff01;先來理解理解內存空間吧&#xff01;請看下圖&#xff1a; 如上圖所示&#xff0c;內存只不…

springboot_yml配置

server: port: 8097 session-timeout: 30 tomcat.max-threads: 0 tomcat.uri-encoding: UTF-8 spring: application: name: feedback # 數據庫配置 datasource: name: test #url: jdbc:mysql://192.168.0.180:3306/dsdb #url: jdbc:m…

Python 字符串查找子串的方法之 index() 和 find()

find(substr, beg0, endlen(string)): 在[beg, end]范圍內查找substring&#xff0c;找到返回substr的起始下標&#xff0c;否則返回 -1。 1 string Hello Python 2 print(string.find(h, 0, len(string))) # 輸出 9 3 print(string.find(thon) # 輸出 84 print(strin.find(…

sqlite 設置向下遞增

因為 sqlite是沒有floor函數的 所以用 cast(x as int) - (x < cast(x as int)) 原理 cast(1.1 as int) 1 cast(-1.1 as int) -1&#xff08;我們想要的結果為2&#xff09; 如果x為非負 cast(x as int)是可以的 但是有負的話就加上后面 (x < cast(x as int))…

Docker 是什么,組成

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、Docker 是一個開源的應用容器引擎&#xff0c;讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中&#xff0c;然后發布到任…