Python中的__new__與__init__魔術(shù)方法理解筆記
很喜歡Python這門語言。在看過語法后學(xué)習(xí)了Django 這個 Web 開發(fā)框架。算是對 Python 有些熟悉了。不過對里面很多東西還是不知道,因?yàn)橛玫纳?。今天學(xué)習(xí)了兩個魔術(shù)方法:__new__ 和 __init__。
開攻:
如果對 Python 有所簡單了解的話應(yīng)該知道它包含類這個概念的。語法如下:
class ClassName:
<statement - 1>:
.
.
.
<statement - N>
問題來了。像我們學(xué)習(xí)的 C# 或是 Java 這些語言中,聲明類時,都是有構(gòu)造函數(shù)的。類似下面這樣子:
public class ClassName{
public ClassName(){
}
}
當(dāng)然訪問修飾符不一定非得 public ,這不是重點(diǎn)就不啰嗦了。那 Python 中的構(gòu)造函數(shù)是怎樣的呢?我自己的理解是它是沒有構(gòu)造函數(shù)的。只不過在初始化時會調(diào)用一些內(nèi)部的可被改變的方法。比如:__new__ 和 __init__ 。從字面意思理解 __new__ 應(yīng)該會在 __init__ 之前執(zhí)行,實(shí)際查了資料后確實(shí)是如此的。官方文檔中關(guān)于 __init__ 方法有這樣一句話:
Many classes like to create objects with instances customized to a specific initial state. Therefore a class may define a special method named __init__()
意思就是說在創(chuàng)建類時,如果想指定的它的初始狀態(tài),那么可以通過定義一個指定名稱為 __init__ 的方法去實(shí)現(xiàn)這樣的功能。這樣說來 __new__ 并不是官方推薦的初始化類時要使用的方法。但是 __new__ 卻是在 __init__ 之前執(zhí)行的。官方文檔中對 __init__ 介紹的第一句便是:當(dāng)創(chuàng)建實(shí)例時調(diào)用 __init__ 方法(Called when the instance is created.),后面又介紹說,如果想調(diào)用基類的 __init__方法必須顯式的調(diào)用,只繼承基類在初始化子類時并不會自動調(diào)用基類的 __init__ 方法。到此應(yīng)該算是對 __init__ 方法了解了。
下面我們看一下 __new__ 方法是怎么回事兒。先看一下官方文檔:
Called to create a new instance of class cls. __new__() is a static method (special-cased so you need not declare it as such) that takes the class of which an instance was requested as its first argument. The remaining arguments are those passed to the object constructor expression (the call to the class). The return value of __new__() should be the new object instance (usually an instance of cls).
Typical implementations create a new instance of the class by invoking the superclass's __new__() method using super(currentclass, cls).__new__(cls[, ...]) with appropriate arguments and then modifying the newly-created instance as necessary before returning it.
If __new__() returns an instance of cls, then the new instance's __init__() method will be invoked like __init__(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to __new__().
If __new__() does not return an instance of cls, then the new instance's __init__() method will not be invoked.
__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.
從這里可以看出來,這個方法才是產(chǎn)生類的實(shí)例的地方。當(dāng)實(shí)例創(chuàng)建完成就調(diào)用 __init__ 方法,初始化類的內(nèi)部狀態(tài)值。文檔中還提到 __new__ 方法其實(shí)是一個靜態(tài)方法,不用每次定義類的時候都聲明這個方法,因?yàn)樵诎姹?2.4 之后 object 是所有對象的基類,而 __new__ 是定義在 object 對象內(nèi)部的靜態(tài)方法。
到這兒其實(shí)就差不多了,就按字面意思理解就可以。 __new__ 用于創(chuàng)建對象,而 __init__ 是在創(chuàng)建完成之后初始化對象狀態(tài)。前兩天看到一個有趣的方法,通過使用 __new__ 應(yīng)用了單例模式在對象身上。
注意點(diǎn):在類繼承中,當(dāng)子類和父類都定義了自己的 __new__ 方法時,那么會先調(diào)用子類的 __new__ 方法再調(diào)用父類的。這一點(diǎn)倒是和 C# 中的繼承是一樣的。其實(shí)仔細(xì)想想 Python 中只不過是把初始化和創(chuàng)建對象這兩個概念分開了,而 C# 中即沒有這么干,只給了構(gòu)造函數(shù),開發(fā)者可以自己看著辦。從這一點(diǎn)兒上說我覺得 Python 的做法我更喜歡。
結(jié)束:
今天算是又學(xué)習(xí)到了新知識,自己挺開心的。再實(shí)踐實(shí)踐。。。
- python __init__與 __new__的區(qū)別
- Python中class內(nèi)置方法__init__與__new__作用與區(qū)別解析
- Python中__new__和__init__的區(qū)別與聯(lián)系
- Python函數(shù)__new__及__init__作用及區(qū)別解析
- 深入理解Python中的 __new__ 和 __init__及區(qū)別介紹
- 淺談python中的__init__、__new__和__call__方法
- 詳解Python中的__new__、__init__、__call__三個特殊方法
- Python中__new__與__init__方法的區(qū)別詳解
- Python中__init__和__new__的區(qū)別詳解
- python中的__init__ 、__new__、__call__小結(jié)
- 詳解Python中的__init__和__new__
- 詳解Python中__new__和__init__的區(qū)別與聯(lián)系
相關(guān)文章
Python編程調(diào)用百度API實(shí)現(xiàn)地理位置經(jīng)緯度坐標(biāo)轉(zhuǎn)換示例
這篇文章主要介紹了Python編程調(diào)用百度API來實(shí)現(xiàn)地理位置經(jīng)緯度坐標(biāo)轉(zhuǎn)換的示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10
如何在Django中設(shè)置定時任務(wù)的方法示例
這篇文章主要介紹了如何在Django中設(shè)置定時任務(wù)的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-01-01
Python?Paramiko上傳下載sftp文件及遠(yuǎn)程執(zhí)行命令詳解
這篇文章主要為大家介紹了Python?Paramiko上傳下載sftp文件及遠(yuǎn)程執(zhí)行命令示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
python實(shí)現(xiàn)感知機(jī)線性分類模型示例代碼
這篇文章主要給大家介紹了關(guān)于python實(shí)現(xiàn)感知機(jī)線性分類模型的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
Python中dumps與dump及l(fā)oads與load的區(qū)別
這篇文章主要介紹了Python中dumps與dump、loads與load的區(qū)別,json模塊提供了一種很簡單的方式來編碼和解碼JSON數(shù)據(jù)。其中兩個主要的函數(shù)是json.dumps()和json.loads(),需要的朋友可以參考下2022-04-04
Python?pyinstaller打包exe最新完整圖文教程
pyinstaller是一個非常簡單的打包python的py文件的庫,下面這篇文章主要給大家介紹了關(guān)于Python?pyinstaller打包exe的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12
Python實(shí)現(xiàn)樹莓派WiFi斷線自動重連的實(shí)例代碼
實(shí)現(xiàn) WiFi 斷線自動重連,原理是用 Python 監(jiān)測網(wǎng)絡(luò)是否斷線,如果斷線則重啟網(wǎng)絡(luò)服務(wù)。接下來給大家分享實(shí)現(xiàn)代碼,需要的朋友參考下2017-03-03

