python面向?qū)ο笾翟惖穆暶髦芷谠斀?/h1>
更新時(shí)間:2023年05月02日 08:40:23 作者:真的不能告訴你我的名字
這篇文章主要介紹python的元類生命周期,我們可以和之前探討類的生命中周期一樣,我們寫一個(gè)案例,使用print來輸出一些信息,來判斷如果基于元類而言,那么生命周期是怎么樣的,文中有詳細(xì)的代碼示例,需要的朋友可以參考下
元類的生命周期
我們之前介紹過,關(guān)于類的生命周期,這里先簡(jiǎn)單回顧下,如果將類實(shí)例化對(duì)象后,會(huì)執(zhí)行內(nèi)置方法為:會(huì)先執(zhí)行__new__
內(nèi)置方法 而后會(huì)執(zhí)行 __init__
內(nèi)置方法。當(dāng)我們執(zhí)行對(duì)象的時(shí)候,會(huì)執(zhí)行__call__
內(nèi)置方法。
如果該類不是基于type
來創(chuàng)建的,而是基于我們自己的元類,那么生命周期應(yīng)該是怎么樣的呢?
我們可以和之前探討類的生命中周期一樣,我們寫一個(gè)案例,使用print
來輸出一些信息,來判斷如果基于元類而言,那么生命周期是怎么樣的。
我們定義代碼如下:

上述代碼,我們將類ClassName
和其元類mateClass
,我們都重寫了__init__
、__call__
、__new__
以及__del__
方法。我們暫時(shí)先不管這些方法中的語句含義,我們先執(zhí)行一次代碼,看看執(zhí)行結(jié)果:

哎,你是否感覺好奇,為什么我們還沒有開始執(zhí)行c = ClassName()
就已經(jīng)執(zhí)行了mateClass
類中的__new__
方法 和 __init__
方法呢?
這是因?yàn)槲覀冊(cè)诙xClassName
類的時(shí)候指定了其元類mateClass
,所以當(dāng)我們定義ClassName
的時(shí)候,就會(huì)去執(zhí)行該元類的__new__
方法 和 __init__
方法。
隨后我們執(zhí)行了c = ClassName()
,這個(gè)是它會(huì)執(zhí)行mateClass
的__call__
方法,我們之前有介紹過,__call__
方法不是要c()
才調(diào)用么? 為什么這里調(diào)用了呢?
這是因?yàn)槲覀冎付ㄔ惖臅r(shí)候,代碼如下:
class ClassName(metaclass=mateClass):
這里打個(gè)比方,上述代碼它相當(dāng)于定義了一個(gè)ClassName
,其類型為mateClass
,所以當(dāng)我們?cè)趫?zhí)行c = ClassName()
就會(huì)觸發(fā)其類的__call__
方法,所以會(huì)執(zhí)行ClassName
的__call__
方法。
隨后才執(zhí)行ClassName
的__new__
方法 和 __init__
方法。而后執(zhí)行函數(shù),最后銷毀的時(shí)候,先銷毀ClassName
再 銷毀mateClass
。
那我們將其整理一下的話,可以圖示為:

元類是如何控制類的創(chuàng)建過程的
上面已經(jīng)演示了元類的生命周期,本篇文章我們將來看下,元類是如何控制類的創(chuàng)建過程的。
在此之前,我們要知道,元類通過什么樣的方式來定義的類,可以看到我們上述的代碼,在元類中的__new__
方法中,我們返回了如下語句:
class mateClass(type):
def __new__(cls, *args, **kwargs):
newCls = super().__new__(cls, *args, **kwargs)
return newCls
該語句會(huì)創(chuàng)建一個(gè)新類,隨后將該類返回回去。
所謂的控制類的創(chuàng)建過程,我們就可以在該__new__
中判斷,傳入的參數(shù)等信息,比如說,我們想要嚴(yán)格規(guī)定創(chuàng)建的類名,不少于6個(gè)字符,不多于20個(gè)字符,這個(gè)如何如何編寫呢? 我們可以在元類中的__new__
方法下獲取傳上來的類名,而后將其對(duì)比,若符合規(guī)則則返回類,若不符合規(guī)則,跑拋錯(cuò):
class mateClass(type):
def __new__(cls, *args, **kwargs):
classname = args[0]
nameLen = len(classname)
if nameLen >= 6 and nameLen <= 20:
newCls = super().__new__(cls, *args, **kwargs)
return newCls
else:
msg = "Class name %s does not meet the specifications" % (classname)
上述代碼,使我們定義了一個(gè)類mateClass
,其繼承type
類,在該類中,我們重寫了__new__
方法,在該方法中,我們首先獲取類名args[0]
將其賦值給classname
,而后進(jìn)行匹配,若長(zhǎng)度大于6且小于20,則創(chuàng)建類,否則就拋錯(cuò)。
介于此,我們可以創(chuàng)建類,將元類指向mateClass
,例如:
class ClassName(metaclass=mateClass):
pass
該類名就符合規(guī)則,不會(huì)報(bào)錯(cuò),若將名稱更換為其他不符合規(guī)則的名稱,則會(huì)拋錯(cuò):
例如:
class d123(metaclass=mateClass):
pass

若我們將名稱修改為長(zhǎng)名稱,如:
class d888888888888888abdassd(metaclass=mateClass):
pass
這個(gè)案例就是所謂的使用元類來控制類的創(chuàng)建等。非常靈活,也非常強(qiáng)大。
總結(jié)
本篇文章,我們先介紹了元類的生命周期,元類的生命周期為,在定義類a
指定其元類時(shí)候,元類就會(huì)執(zhí)行__new__
,__init__
方法。在將類a
給實(shí)例化的時(shí)候,就會(huì)執(zhí)行元類的__call__
方法。后面就和普通的類調(diào)用生命周期差不多。后面我們介紹了元類是如何控制類的創(chuàng)建過程的,我們介紹了幾個(gè)例子來說明該功能。
到此這篇關(guān)于python面向?qū)ο笾翟惖穆暶髦芷谠斀獾奈恼戮徒榻B到這了,更多相關(guān)python元類聲明周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
-
python+adb+monkey實(shí)現(xiàn)Rom穩(wěn)定性測(cè)試詳解
這篇文章主要介紹了python+adb+monkey實(shí)現(xiàn)Rom穩(wěn)定性測(cè)試詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧 2020-04-04
-
Android基于TCP和URL協(xié)議的網(wǎng)絡(luò)編程示例【附demo源碼下載】
這篇文章主要介紹了Android基于TCP和URL協(xié)議的網(wǎng)絡(luò)編程,結(jié)合實(shí)例形式分析了Android網(wǎng)絡(luò)編程的通信原理、實(shí)現(xiàn)步驟與相關(guān)操作技巧,并附帶demo源碼供讀者下載參考,需要的朋友可以參考下 2018-01-01
-
基于Python實(shí)現(xiàn)一個(gè)簡(jiǎn)單的注冊(cè)機(jī)并生成卡密
這篇文章主要為大家詳細(xì)介紹了如何使用Python編寫一個(gè)簡(jiǎn)單而強(qiáng)大的注冊(cè)機(jī),生成卡密來實(shí)現(xiàn)用戶注冊(cè),從而輕松登錄應(yīng)用程序,有需要的小伙伴快可以參考下 2023-12-12
-
跟老齊學(xué)Python之玩轉(zhuǎn)字符串(2)
上一篇文章章中已經(jīng)講到連接兩個(gè)字符串的一種方法,本文繼續(xù)講訴連接字符串的方法2,字符串復(fù)制,字符串長(zhǎng)度,字符大小寫的轉(zhuǎn)換,希望對(duì)大家有所幫助。 2014-09-09
-
python pyautogui手動(dòng)活動(dòng)(模擬鼠標(biāo)鍵盤)自動(dòng)化庫(kù)使用
這篇文章主要為大家介紹了python pyautogui手動(dòng)活動(dòng)(模擬鼠標(biāo)鍵盤)自動(dòng)化庫(kù)使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪 2024-01-01
-
基于Keras中Conv1D和Conv2D的區(qū)別說明
這篇文章主要介紹了基于Keras中Conv1D和Conv2D的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧 2020-06-06
-
Python利用matplotlib實(shí)現(xiàn)動(dòng)態(tài)可視化詳解
Python中的數(shù)據(jù)可視化是指原始數(shù)據(jù)的圖形表示,以更好地可視化、理解和推理,Python提供了各種庫(kù),包含用于可視化數(shù)據(jù)的不同特性,下面我們就來看看如何利用matplotlib實(shí)現(xiàn)動(dòng)態(tài)可視化吧 2023-08-08
-
編譯 pycaffe時(shí)報(bào)錯(cuò):fatal error: numpy/arrayobject.h沒有那個(gè)文件或目錄
這篇文章主要介紹了編譯 pycaffe時(shí)報(bào)錯(cuò):fatal error: numpy/arrayobject.h沒有那個(gè)文件或目錄,需要的朋友可以參考下 2020-11-11
-
在keras里面實(shí)現(xiàn)計(jì)算f1-score的代碼
這篇文章主要介紹了在keras里面實(shí)現(xiàn)計(jì)算f1-score的代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧 2020-06-06
-
Python讀取數(shù)據(jù)集并消除數(shù)據(jù)中的空行方法
今天小編就為大家分享一篇Python讀取數(shù)據(jù)集并消除數(shù)據(jù)中的空行方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧 2018-07-07
最新評(píng)論
元類的生命周期
我們之前介紹過,關(guān)于類的生命周期,這里先簡(jiǎn)單回顧下,如果將類實(shí)例化對(duì)象后,會(huì)執(zhí)行內(nèi)置方法為:會(huì)先執(zhí)行__new__
內(nèi)置方法 而后會(huì)執(zhí)行 __init__
內(nèi)置方法。當(dāng)我們執(zhí)行對(duì)象的時(shí)候,會(huì)執(zhí)行__call__
內(nèi)置方法。
如果該類不是基于type
來創(chuàng)建的,而是基于我們自己的元類,那么生命周期應(yīng)該是怎么樣的呢?
我們可以和之前探討類的生命中周期一樣,我們寫一個(gè)案例,使用print
來輸出一些信息,來判斷如果基于元類而言,那么生命周期是怎么樣的。
我們定義代碼如下:
上述代碼,我們將類ClassName
和其元類mateClass
,我們都重寫了__init__
、__call__
、__new__
以及__del__
方法。我們暫時(shí)先不管這些方法中的語句含義,我們先執(zhí)行一次代碼,看看執(zhí)行結(jié)果:
哎,你是否感覺好奇,為什么我們還沒有開始執(zhí)行c = ClassName()
就已經(jīng)執(zhí)行了mateClass
類中的__new__
方法 和 __init__
方法呢?
這是因?yàn)槲覀冊(cè)诙xClassName
類的時(shí)候指定了其元類mateClass
,所以當(dāng)我們定義ClassName
的時(shí)候,就會(huì)去執(zhí)行該元類的__new__
方法 和 __init__
方法。
隨后我們執(zhí)行了c = ClassName()
,這個(gè)是它會(huì)執(zhí)行mateClass
的__call__
方法,我們之前有介紹過,__call__
方法不是要c()
才調(diào)用么? 為什么這里調(diào)用了呢?
這是因?yàn)槲覀冎付ㄔ惖臅r(shí)候,代碼如下:
class ClassName(metaclass=mateClass):
這里打個(gè)比方,上述代碼它相當(dāng)于定義了一個(gè)ClassName
,其類型為mateClass
,所以當(dāng)我們?cè)趫?zhí)行c = ClassName()
就會(huì)觸發(fā)其類的__call__
方法,所以會(huì)執(zhí)行ClassName
的__call__
方法。
隨后才執(zhí)行ClassName
的__new__
方法 和 __init__
方法。而后執(zhí)行函數(shù),最后銷毀的時(shí)候,先銷毀ClassName
再 銷毀mateClass
。
那我們將其整理一下的話,可以圖示為:
元類是如何控制類的創(chuàng)建過程的
上面已經(jīng)演示了元類的生命周期,本篇文章我們將來看下,元類是如何控制類的創(chuàng)建過程的。
在此之前,我們要知道,元類通過什么樣的方式來定義的類,可以看到我們上述的代碼,在元類中的__new__
方法中,我們返回了如下語句:
class mateClass(type): def __new__(cls, *args, **kwargs): newCls = super().__new__(cls, *args, **kwargs) return newCls
該語句會(huì)創(chuàng)建一個(gè)新類,隨后將該類返回回去。
所謂的控制類的創(chuàng)建過程,我們就可以在該__new__
中判斷,傳入的參數(shù)等信息,比如說,我們想要嚴(yán)格規(guī)定創(chuàng)建的類名,不少于6個(gè)字符,不多于20個(gè)字符,這個(gè)如何如何編寫呢? 我們可以在元類中的__new__
方法下獲取傳上來的類名,而后將其對(duì)比,若符合規(guī)則則返回類,若不符合規(guī)則,跑拋錯(cuò):
class mateClass(type): def __new__(cls, *args, **kwargs): classname = args[0] nameLen = len(classname) if nameLen >= 6 and nameLen <= 20: newCls = super().__new__(cls, *args, **kwargs) return newCls else: msg = "Class name %s does not meet the specifications" % (classname)
上述代碼,使我們定義了一個(gè)類mateClass
,其繼承type
類,在該類中,我們重寫了__new__
方法,在該方法中,我們首先獲取類名args[0]
將其賦值給classname
,而后進(jìn)行匹配,若長(zhǎng)度大于6且小于20,則創(chuàng)建類,否則就拋錯(cuò)。
介于此,我們可以創(chuàng)建類,將元類指向mateClass
,例如:
class ClassName(metaclass=mateClass): pass
該類名就符合規(guī)則,不會(huì)報(bào)錯(cuò),若將名稱更換為其他不符合規(guī)則的名稱,則會(huì)拋錯(cuò):
例如:
class d123(metaclass=mateClass): pass
若我們將名稱修改為長(zhǎng)名稱,如:
class d888888888888888abdassd(metaclass=mateClass): pass
這個(gè)案例就是所謂的使用元類來控制類的創(chuàng)建等。非常靈活,也非常強(qiáng)大。
總結(jié)
本篇文章,我們先介紹了元類的生命周期,元類的生命周期為,在定義類a
指定其元類時(shí)候,元類就會(huì)執(zhí)行__new__
,__init__
方法。在將類a
給實(shí)例化的時(shí)候,就會(huì)執(zhí)行元類的__call__
方法。后面就和普通的類調(diào)用生命周期差不多。后面我們介紹了元類是如何控制類的創(chuàng)建過程的,我們介紹了幾個(gè)例子來說明該功能。
到此這篇關(guān)于python面向?qū)ο笾翟惖穆暶髦芷谠斀獾奈恼戮徒榻B到這了,更多相關(guān)python元類聲明周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python+adb+monkey實(shí)現(xiàn)Rom穩(wěn)定性測(cè)試詳解
這篇文章主要介紹了python+adb+monkey實(shí)現(xiàn)Rom穩(wěn)定性測(cè)試詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04Android基于TCP和URL協(xié)議的網(wǎng)絡(luò)編程示例【附demo源碼下載】
這篇文章主要介紹了Android基于TCP和URL協(xié)議的網(wǎng)絡(luò)編程,結(jié)合實(shí)例形式分析了Android網(wǎng)絡(luò)編程的通信原理、實(shí)現(xiàn)步驟與相關(guān)操作技巧,并附帶demo源碼供讀者下載參考,需要的朋友可以參考下2018-01-01基于Python實(shí)現(xiàn)一個(gè)簡(jiǎn)單的注冊(cè)機(jī)并生成卡密
這篇文章主要為大家詳細(xì)介紹了如何使用Python編寫一個(gè)簡(jiǎn)單而強(qiáng)大的注冊(cè)機(jī),生成卡密來實(shí)現(xiàn)用戶注冊(cè),從而輕松登錄應(yīng)用程序,有需要的小伙伴快可以參考下2023-12-12跟老齊學(xué)Python之玩轉(zhuǎn)字符串(2)
上一篇文章章中已經(jīng)講到連接兩個(gè)字符串的一種方法,本文繼續(xù)講訴連接字符串的方法2,字符串復(fù)制,字符串長(zhǎng)度,字符大小寫的轉(zhuǎn)換,希望對(duì)大家有所幫助。2014-09-09python pyautogui手動(dòng)活動(dòng)(模擬鼠標(biāo)鍵盤)自動(dòng)化庫(kù)使用
這篇文章主要為大家介紹了python pyautogui手動(dòng)活動(dòng)(模擬鼠標(biāo)鍵盤)自動(dòng)化庫(kù)使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01基于Keras中Conv1D和Conv2D的區(qū)別說明
這篇文章主要介紹了基于Keras中Conv1D和Conv2D的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-06-06Python利用matplotlib實(shí)現(xiàn)動(dòng)態(tài)可視化詳解
Python中的數(shù)據(jù)可視化是指原始數(shù)據(jù)的圖形表示,以更好地可視化、理解和推理,Python提供了各種庫(kù),包含用于可視化數(shù)據(jù)的不同特性,下面我們就來看看如何利用matplotlib實(shí)現(xiàn)動(dòng)態(tài)可視化吧2023-08-08編譯 pycaffe時(shí)報(bào)錯(cuò):fatal error: numpy/arrayobject.h沒有那個(gè)文件或目錄
這篇文章主要介紹了編譯 pycaffe時(shí)報(bào)錯(cuò):fatal error: numpy/arrayobject.h沒有那個(gè)文件或目錄,需要的朋友可以參考下2020-11-11在keras里面實(shí)現(xiàn)計(jì)算f1-score的代碼
這篇文章主要介紹了在keras里面實(shí)現(xiàn)計(jì)算f1-score的代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-06-06Python讀取數(shù)據(jù)集并消除數(shù)據(jù)中的空行方法
今天小編就為大家分享一篇Python讀取數(shù)據(jù)集并消除數(shù)據(jù)中的空行方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-07-07