日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python元类_python中的元类 metaclass

發(fā)布時(shí)間:2023/12/19 python 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python元类_python中的元类 metaclass 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

python中的元類 metaclass

在python中,類(class)本身也是一個(gè)實(shí)例對(duì)象, 它的類型則是元類, 如果沒有指明, 則自定義類的類型是type. 換言之, 我們所定義的普通類都是type的實(shí)例對(duì)象, 如果一個(gè)類繼承了type, 那么這個(gè)類就是元類.

1. 什么是元類

一個(gè)類繼承了type,那么這個(gè)類就是元類

class A(type):

pass

A就是一個(gè)元類,元類能用來做什么呢,應(yīng)該說,絕大多數(shù)時(shí)候都用不上元類,如果你想使用元類,請(qǐng)確保你非常理解它

2. 元類的__new__方法

在定義一個(gè)類時(shí),指定metaclass,就意味著這個(gè)類將有所指定的metaclass來創(chuàng)建

class MyMeta(type):

def __new__(cls, *args, **kwargs):

_class = super().__new__(cls, *args, **kwargs)

print(_class.__name__)

return _class

class Animal(metaclass=MyMeta):

def __init__(self, name):

self.name = name

類MyMeta是元類,在定義Animal這個(gè)類時(shí),我指定了它的元類是MyMeta,因此,類Animal將由MyMeta的__new__方法來創(chuàng)建,換一個(gè)角度來描述,類Animal是類MyMeta的實(shí)例對(duì)象。在MyMeta的__new__方法中,我使用print語句輸出了__class的__name__屬性,理論分析告訴我們,這個(gè)值應(yīng)該是Animal, 實(shí)際結(jié)果也確實(shí)是如此。

元類是用來創(chuàng)建普通類(自定義類)的,我們可以利用元類對(duì)普通類進(jìn)行一些限制和要求,比如,我們可以要求所有繼承Animal的類必須擁有run方法

from inspect import isfunction

class MyMeta(type):

def __new__(cls, *args, **kwargs):

_class = super().__new__(cls, *args, **kwargs)

if _class.__name__ != 'Animal':

if not hasattr(_class, 'run') or not isfunction(getattr(_class, 'run')):

raise Exception('類{name}沒有實(shí)現(xiàn)run方法'.format(name=_class.__name__))

return _class

class Animal(metaclass=MyMeta):

def __init__(self, name):

self.name = name

class Cat(Animal):

def __init__(self, name):

super().__init__(name)

cat = Cat('加菲貓')

類Cat繼承了Animal,那么它的元類也是MyMeta,在MyMeta的__new__方法里將創(chuàng)建出類Cat,創(chuàng)建以后會(huì)檢查類Cat是否有run屬性且該屬性是一個(gè)函數(shù),如果不滿足條件則拋出異常。如果類Cat實(shí)現(xiàn)了run方法,那么上述代碼將正常執(zhí)行

class Cat(Animal):

def __init__(self, name):

super().__init__(name)

def run(self):

print('run')

cat = Cat('加菲貓')

cat.run()

我們務(wù)必想清楚一點(diǎn),盡管我們?cè)谀_本里使用class定義了類Cat, 但并不是真正的創(chuàng)建了類Cat,我們所寫的代碼僅僅是一個(gè)定義,創(chuàng)建的過程使用元類MyMeta來完成的。

3. 元類的__init__方法

元類的__new__負(fù)責(zé)構(gòu)建普通類,__init__負(fù)責(zé)對(duì)這個(gè)普通類進(jìn)行初始化

from inspect import isfunction

class MyMeta(type):

def __new__(cls, *args, **kwargs):

_class = super().__new__(cls, *args, **kwargs)

if _class.__name__ != 'Animal':

if not hasattr(_class, 'run') or not isfunction(getattr(_class, 'run')):

raise Exception('類{name}沒有實(shí)現(xiàn)run方法'.format(name=_class.__name__))

return _class

def __init__(self, *args, **kwargs):

super().__init__(*args, **kwargs)

self.home = 'earth'

class Animal(metaclass=MyMeta):

def __init__(self, name):

self.name = name

class Cat(Animal):

def __init__(self, name):

super().__init__(name)

def run(self):

print('run')

print(Animal.home)

print(Cat.home)

在元類的__init__方法里,self參數(shù)就是我們所創(chuàng)建的類,Animal和Cat, 我們?yōu)樗麄冊(cè)黾恿祟悓傩詇ome, 重載__init__方法,可以更加優(yōu)雅的實(shí)現(xiàn)單例模式

class Singleton(type):

def __init__(self, *args, **kwargs):

self.__instance = None

super().__init__(*args, **kwargs)

def __call__(self, *args, **kwargs):

if self.__instance is None:

self.__instance = super().__call__(*args, **kwargs)

return self.__instance

else:

return self.__instance

class FileLock(metaclass=Singleton):

pass

file_lock_1 = FileLock()

file_lock_2 = FileLock()

print(file_lock_1 is file_lock_2)

4. 元類的__call__方法

class MyMeta(type):

def __call__(self, *args, **kwargs):

raise TypeError('不能創(chuàng)建實(shí)例')

class FileTool(metaclass=MyMeta):

@staticmethod

def iter_folder(path):

print('遍歷文件夾')

ft = FileTool()

上面的代碼執(zhí)行會(huì)報(bào)錯(cuò)

Traceback (most recent call last):

File "/Users/kwsy/kwsy/coolpython/demo.py", line 13, in

ft = FileTool()

File "/Users/kwsy/kwsy/coolpython/demo.py", line 5, in __call__

raise TypeError('不能創(chuàng)建實(shí)例')

TypeError: 不能創(chuàng)建實(shí)例

類FileTool是元類MyMeta的一個(gè)示例,那么當(dāng)執(zhí)行FileTool()時(shí),不正是在調(diào)用元類MyMeta的__call__方法么,而MyMeta的__call__方法偏偏拋出一個(gè)類型異常,這就導(dǎo)致FileTool不能被實(shí)例化,我們只能使用它的靜態(tài)方法。

重載元類的__call__方法和類cat的__del__方法可以讓我們控制類的實(shí)例化過程,我們可以控制一個(gè)類的實(shí)例數(shù)量

class MyMeta(type):

def __init__(self, *args, **kwargs):

self.instance_count = 0

super().__init__(*args, **kwargs)

def __call__(self, *args, **kwargs):

if self.instance_count < 3:

self.instance_count += 1

return type.__call__(self, *args, **kwargs)

else:

raise Exception("類{name}的實(shí)例總數(shù)超出限制".format(name=self.__name__))

def __del__(self):

self.instance_count -= 1

class Cat(metaclass=MyMeta):

def __init__(self, name):

self.name = name

def __del__(self):

Cat.instance_count -= 1

c1 = Cat('c1')

c2 = Cat('c2')

c3 = Cat('c3')

c4 = Cat('c4')

上面的代碼中,當(dāng)創(chuàng)c4的時(shí)候會(huì)拋出異常,因?yàn)閷?shí)例的數(shù)量已經(jīng)達(dá)到上限,想要?jiǎng)?chuàng)建c4,必須銷毀一個(gè)之前創(chuàng)建的對(duì)象實(shí)例

c1 = Cat('c1')

c2 = Cat('c2')

c3 = Cat('c3')

del c1

c4 = Cat('c4')

銷毀c1時(shí),類屬性instance_count執(zhí)行了減一操作,因此可以創(chuàng)建出c4。

5.小結(jié)

以上示例代碼,不保證有工程實(shí)踐意義,純粹是為了講解元類的功能作用而認(rèn)為制造出來的,坦率的講,在實(shí)際工作中,幾乎用不到元類,但我仍然秉持一個(gè)觀點(diǎn):面試造火箭,工作擰螺絲的意義在于,能造火箭的人必然牛逼,你可以放心的把擰螺絲的工作交給他,至于是否浪費(fèi)資源,如果你不會(huì)造火箭,那么請(qǐng)慎言,這還不是你這個(gè)層次所能討論的問題。

總結(jié)

以上是生活随笔為你收集整理的python元类_python中的元类 metaclass的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 精品视频在线观看 | 国产精品夜夜夜爽张柏芝 | 亚洲精品视 | 污污内射久久一区二区欧美日韩 | 中文字幕日韩一区二区三区不卡 | 免费av在线播放网址 | 国产欧美高清 | 成人特级毛片69免费观看 | 狠狠躁夜夜躁人人爽视频 | 精品久久五月天 | 日本在线视频www | 在线视频黄 | 国产天天射 | 国产精品99一区 | 男人的天堂狠狠干 | 日本视频在线观看 | 日韩网站在线播放 | 欧美a在线观看 | 亚欧视频在线观看 | 精品区一区二区 | 日本一区二区在线免费观看 | 国产精品一区视频 | av天天操| 欧美精品1区2区3区 精品成人一区 | 国产毛片毛片毛片 | 中文字幕在线看人 | 四虎成人精品永久免费av九九 | 久久久久一区 | 国产性xxxx高清 | 少妇姐姐| 国产精品桃色 | 91成品视频 | 日韩毛片av| 自拍视频国产 | 轮番上阵免费观看在线电影 | 男女免费视频网站 | 国产一区免费看 | 男女做爰猛烈刺激 | 日本黄色中文字幕 | 成人午夜天 | 无码国产69精品久久久久同性 | 国语一区 | 国产麻豆一区二区 | 香蕉视频在线网址 | 日韩欧美h | 97色伦97色伦国产欧美空 | www.天天色 | av亚洲在线 | 日产精品久久久 | 狠色综合7777夜色撩人 | 两个人做羞羞的视频 | a级在线看| 亚洲成人黄色网 | 欧美视频第一区 | 操操插插 | 屁屁影院一区二区三区 | 欧美又粗又长又爽做受 | 日韩久久影院 | a在线| 特黄aaaaaaa片免费视频 | 综合久久综合 | 亚洲中文字幕在线观看 | 久久久久久国产精品免费播放 | 秋霞久久精品 | 鲁一鲁在线视频 | av资源网在线观看 | 69精品一区二区三区 | 午夜精品一区二区三区三上悠亚 | 天天色天天综合 | 亚洲春色av | 欧美高清精品一区二区 | 福利电影一区二区三区 | 国产高清在线观看视频 | 久久久精品久久久 | 亚洲自拍偷拍视频 | 婷婷激情在线 | 怡红院成人影院 | 国产高中女学生第一次 | 37p粉嫩大胆色噜噜噜 | 国产成人精品久久二区二区91 | 美梦视频大全在线观看高清 | 致单身男女免费观看完整版 | 特级西西人体444www高清 | 另类av在线| 中文字幕在线看人 | 午夜性剧场 | 无码国产伦一区二区三区视频 | 久久免费福利 | 伊人影视久久 | 你懂的国产视频 | 波多野结衣亚洲视频 | 日本久久视频 | 日韩激情网址 | 精品乱子伦一区二区三区 | 成人在线观看免费视频 | 都市激情校园春色亚洲 | 欧美.com | av日韩在线免费观看 | 男生把女生困困的视频 |