python面向對象值元類的聲明周期詳解
元類的生命周期
我們之前介紹過,關于類的生命周期,這里先簡單回顧下,如果將類實例化對象后,會執(zhí)行內置方法為:會先執(zhí)行__new__內置方法 而后會執(zhí)行 __init__內置方法。當我們執(zhí)行對象的時候,會執(zhí)行__call__內置方法。
如果該類不是基于type來創(chuàng)建的,而是基于我們自己的元類,那么生命周期應該是怎么樣的呢?
我們可以和之前探討類的生命中周期一樣,我們寫一個案例,使用print來輸出一些信息,來判斷如果基于元類而言,那么生命周期是怎么樣的。
我們定義代碼如下:

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

哎,你是否感覺好奇,為什么我們還沒有開始執(zhí)行c = ClassName()就已經執(zhí)行了mateClass類中的__new__方法 和 __init__方法呢?
這是因為我們在定義ClassName類的時候指定了其元類mateClass,所以當我們定義ClassName的時候,就會去執(zhí)行該元類的__new__方法 和 __init__方法。
隨后我們執(zhí)行了c = ClassName(),這個是它會執(zhí)行mateClass的__call__方法,我們之前有介紹過,__call__方法不是要c()才調用么? 為什么這里調用了呢?
這是因為我們指定元類的時候,代碼如下:
class ClassName(metaclass=mateClass):
這里打個比方,上述代碼它相當于定義了一個ClassName,其類型為mateClass,所以當我們在執(zhí)行c = ClassName()就會觸發(fā)其類的__call__方法,所以會執(zhí)行ClassName的__call__方法。
隨后才執(zhí)行ClassName的__new__方法 和 __init__方法。而后執(zhí)行函數,最后銷毀的時候,先銷毀ClassName 再 銷毀mateClass。
那我們將其整理一下的話,可以圖示為:

元類是如何控制類的創(chuàng)建過程的
上面已經演示了元類的生命周期,本篇文章我們將來看下,元類是如何控制類的創(chuàng)建過程的。
在此之前,我們要知道,元類通過什么樣的方式來定義的類,可以看到我們上述的代碼,在元類中的__new__方法中,我們返回了如下語句:
class mateClass(type):
def __new__(cls, *args, **kwargs):
newCls = super().__new__(cls, *args, **kwargs)
return newCls該語句會創(chuàng)建一個新類,隨后將該類返回回去。
所謂的控制類的創(chuàng)建過程,我們就可以在該__new__中判斷,傳入的參數等信息,比如說,我們想要嚴格規(guī)定創(chuàng)建的類名,不少于6個字符,不多于20個字符,這個如何如何編寫呢? 我們可以在元類中的__new__方法下獲取傳上來的類名,而后將其對比,若符合規(guī)則則返回類,若不符合規(guī)則,跑拋錯:
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)上述代碼,使我們定義了一個類mateClass,其繼承type類,在該類中,我們重寫了__new__方法,在該方法中,我們首先獲取類名args[0]將其賦值給classname,而后進行匹配,若長度大于6且小于20,則創(chuàng)建類,否則就拋錯。
介于此,我們可以創(chuàng)建類,將元類指向mateClass,例如:
class ClassName(metaclass=mateClass):
pass該類名就符合規(guī)則,不會報錯,若將名稱更換為其他不符合規(guī)則的名稱,則會拋錯:
例如:
class d123(metaclass=mateClass):
pass
若我們將名稱修改為長名稱,如:
class d888888888888888abdassd(metaclass=mateClass):
pass這個案例就是所謂的使用元類來控制類的創(chuàng)建等。非常靈活,也非常強大。
總結
本篇文章,我們先介紹了元類的生命周期,元類的生命周期為,在定義類a指定其元類時候,元類就會執(zhí)行__new__,__init__方法。在將類a給實例化的時候,就會執(zhí)行元類的__call__方法。后面就和普通的類調用生命周期差不多。后面我們介紹了元類是如何控制類的創(chuàng)建過程的,我們介紹了幾個例子來說明該功能。
到此這篇關于python面向對象值元類的聲明周期詳解的文章就介紹到這了,更多相關python元類聲明周期內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
python+adb+monkey實現Rom穩(wěn)定性測試詳解
這篇文章主要介紹了python+adb+monkey實現Rom穩(wěn)定性測試詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
Android基于TCP和URL協(xié)議的網絡編程示例【附demo源碼下載】
這篇文章主要介紹了Android基于TCP和URL協(xié)議的網絡編程,結合實例形式分析了Android網絡編程的通信原理、實現步驟與相關操作技巧,并附帶demo源碼供讀者下載參考,需要的朋友可以參考下2018-01-01
python pyautogui手動活動(模擬鼠標鍵盤)自動化庫使用
這篇文章主要為大家介紹了python pyautogui手動活動(模擬鼠標鍵盤)自動化庫使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01
基于Keras中Conv1D和Conv2D的區(qū)別說明
這篇文章主要介紹了基于Keras中Conv1D和Conv2D的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06
Python利用matplotlib實現動態(tài)可視化詳解
Python中的數據可視化是指原始數據的圖形表示,以更好地可視化、理解和推理,Python提供了各種庫,包含用于可視化數據的不同特性,下面我們就來看看如何利用matplotlib實現動態(tài)可視化吧2023-08-08
編譯 pycaffe時報錯:fatal error: numpy/arrayobject.h沒有那個文件或目錄
這篇文章主要介紹了編譯 pycaffe時報錯:fatal error: numpy/arrayobject.h沒有那個文件或目錄,需要的朋友可以參考下2020-11-11

