深入理解Python的元類
什么是元類
Python中,一切皆對(duì)象,我們定義的數(shù)字、字符串、函數(shù)、列表等都是對(duì)象,對(duì)象是類(class)的是實(shí)例,而類(class)其實(shí)也是對(duì)象,是type的實(shí)例。這個(gè)type就是Python中的元類(metaclass)。所謂元類就是用于創(chuàng)建所有類型的類,Python中的所有新式類以及Python3中的所有類都是type元類的實(shí)例。我們看下面這個(gè)例子:
print(type(0)) # <class 'int'>
print(type(int)) # <class 'type'>
print(type("tigeriaf")) # <class 'str'>
print(type(str)) # <class 'type'>
print(type([1, 2, 3])) # <class 'list'>
print(type(list)) # <class 'type'>
class User:
pass
u = User()
print(type(u)) # <class '__main__.User'>
print(type(User)) # <class 'type'>
print(type(type)) # <class 'type'>
type元類動(dòng)態(tài)創(chuàng)建類
之前我們定義類要使用class關(guān)鍵字進(jìn)行創(chuàng)建,除了這樣我們還可以使用type動(dòng)態(tài)的去創(chuàng)建類。
用法如下:
type(name, bases, dict),接收三個(gè)參數(shù)
- 第一個(gè)參數(shù)name是指要?jiǎng)?chuàng)建類的名稱
- 第二個(gè)參數(shù)bases是指需要繼承父類的元組
- 第三個(gè)參數(shù)dict是類的屬性
例如:
class User:
def __init__(self):
self.name = 'tigeriaf'
print(User)
user = User()
print(user.name)
class User:
def __init__(self):
self.name = 'tigeriaf'
print(User)
user = User()
print(user.name)
以上兩種方式都可以創(chuàng)建類,輸出結(jié)果也是一樣的,可見使用type動(dòng)態(tài)的去創(chuàng)建類也是非常方便的。
自定義元類
通過上面的例子我們知道可以使用type(name, bases, dict)來創(chuàng)建類,如果當(dāng)使用type元類無法滿足我們的一些需求時(shí),我們可以自定義一個(gè)元類并使用該元類去創(chuàng)建類嗎?答案是可以的,下面我們來看一下:
class MyMetaClass(type):
def __init__(cls, name, bases, dict):
super().__init__(name, bases, dict)
cls.int_attrs = {}
for k, v in dict.items():
if type(v) is int:
cls.int_attrs[k] = v
User = MyMetaClass('User', (), {'name': 'tigeriaf', "age": 24, "level": 2, "introduction": "Python全菜工程師"})
print(User) # <class '__main__.User'>
user = User()
print(user.name) # tigeriaf
print(user.int_attrs) # {'age': 24, 'level': 2}
也可以使用下面這種方法,去創(chuàng)建繼承元類的類。
class User(metaclass=MyMetaClass):
pass
注意:在Python2中使用元類需要在要?jiǎng)?chuàng)建的類內(nèi)對(duì)__metaclass__進(jìn)行賦值,值為元類。
上述代碼定義一個(gè)類MyMetaClass,繼承自type類,因?yàn)閠ype是元類,所以MyMetaClass也是一個(gè)元類,在__init__通過super().__init__(name, bases, dict)調(diào)用了父類type的__init__()方法,在實(shí)現(xiàn)自定義元類的基礎(chǔ)上,還在創(chuàng)建類的時(shí)候把屬性循環(huán)了一遍,然后值為int類型的屬性單獨(dú)存了起來。這樣我們就實(shí)現(xiàn)了比type元類更定制化的元類了,我們可以隨意在元類內(nèi)添加我們想要的功能。
總結(jié)
總體下來,發(fā)現(xiàn)元類及其使用有些難以理解且看不出有什么特別的地方能讓我們?nèi)ナ褂?,好吧,確實(shí)如此,通常情況下確實(shí)可能用不到它,其實(shí)元類主要就是在類和實(shí)例創(chuàng)建的時(shí)候發(fā)揮作用,來實(shí)現(xiàn)一些功能,如果確實(shí)不清楚什么時(shí)候該去使用的話,那我們就不需要它,當(dāng)真正需要它的時(shí)候,我們可能就會(huì)發(fā)現(xiàn)它的強(qiáng)大之處。
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
基于python requests selenium爬取excel vba過程解析
這篇文章主要介紹了基于python requests selenium爬取excel vba過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
Python?Pygame實(shí)戰(zhàn)之打磚塊小游戲
打磚塊最早是由雅達(dá)利公司開發(fā)的一款獨(dú)立游戲,也是無數(shù)人的童年記憶。本文將利用Python中的Pygame模塊制作經(jīng)典的打磚塊游戲,需要的可以參考一下2022-02-02
python3實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲之BeautifulSoup使用詳解
這篇文章主要介紹了python3實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲之BeautifulSoup使用詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12
一小時(shí)學(xué)會(huì)TensorFlow2之自定義層
這篇文章主要介紹了TensorFlow2之自定義層,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09
Pycharm使用遠(yuǎn)程linux服務(wù)器conda/python環(huán)境在本地運(yùn)行的方法(圖解))
這篇文章主要介紹了Pycharm使用遠(yuǎn)程linux服務(wù)器conda/python環(huán)境在本地運(yùn)行的方法,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12
Python?reversed函數(shù)用法小結(jié)
reversed函數(shù)是Python中的內(nèi)置函數(shù)之一,是對(duì)給定的序列返回一個(gè)逆序序列的迭代器,需要通過遍歷/list/next()等方法獲取作用后的值,本文給大家介紹Python?reversed函數(shù)及用法,感興趣的朋友一起看看吧2023-10-10

