<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
python語言因為工作偏向於 AI ,所以對於這門語言還停留在表面,對於 python 深層並沒有接觸到。
今天來聊一聊元類(metaclass) ,想必大多數人都或多或少聽過超程式設計這個詞,但是對於超程式設計是什麼以及如何應用超程式設計熟悉應該不多,在 python 中的 metaclass 就是幫助 developer 實現超程式設計,因此產生一個想法
最近時間還算寬裕,所以想要文章認真弄一弄
在 python 語言中,並沒有函數過載,我們下面通過一個具體例子來說明。
class A(): def f(self, x:int): print('A.f int overload',self,x) def f(self,x:str): print('A.f str overload',self,x) def f(self,x,y): print('A.f two arg overload',self,x,y) if __name__ == "__main__": a = A() a.f(1)
當執行上面程式碼我們會得到一個錯誤資訊,範例化 A 類後,呼叫範例的 f 方法,因為在 python 語言中沒有重灌方法,所以 def f(self,x:str)
會覆蓋之前的 def f(self, x:int)
, 而 def f(self,x,y)
方法會覆蓋於 def f(self,x:str)
方法,所以當通過傳入 1 一個引數,不會呼叫 def f(self,x:int)
而是呼叫 def f(self,x,y)
方法。
TypeError: f() missing 1 required positional argument: 'y'
那麼什麼是正確的姿勢解決這個問題呢? 這裡先不急於給出答案,當我們介紹完 metaclass 後,答案就自然浮出水面。
想要了解 Metaclass 也就是元類,meta 在英文中超越的意思,也就是 Metaclass 是高階於 class,用於建立 class 的 class。有的時候我們需要控制類建立過程,通常建立類工作是由 type 完成的,因為 type 直接設計到 c,我們希望在 type 建立類過程插入一些自定義的東西,所以引入了 Metaclass 讓某一個類建立工作不再由 type 來實現,而是由指定 class 來實現
在 python 中,我們可以通過 class 來範例化物件,不過這裡要說在 python 中 class 其實也是物件。既然 class 也是物件,那麼 class 的型別又是什麼呢
class A: a = 1 b = "hello" def f(self): return 12 def main(): print(f'{type(2)=}') print(f'{type("hello")=}') print(f'{type([])=}') print(f'{type(A())=}') if __name__ == "__main__": main()
輸出一下 2、hello 、空陣列和 A 類範例的型別,結果發現他們類別分別為 int、str、list 和 A 類別。其實他們也是物件,既然是物件,那麼就會有一個 class 用於建立這個類別。
type(2)=<class 'int'> type("hello")=<class 'str'> type([])=<class 'list'> type(A())=<class '__main__.A'>
接下來我們就看一下這些 class(int,str,list) 那麼這些物件又是什麼類別呢
class A: a = 1 b = "hello" def f(self): return 12 if __name__ == "__main__": print(f'{type(int)=}') print(f'{type(str)=}') print(f'{type(list)=}') print(f'{type(A)=}')
type(int)=<class 'type'> type(str)=<class 'type'> type(list)=<class 'type'> type(A)=<class 'type'>
不難看出多有 class 的型別都是 type ,例如數位 2 的 int 的一個範例,而 int 又是 type 的一個範例。
如果大家從類似 java 這些語言開始,然後再去學習 python 可能會有這樣疑問,在 python 中 type 和 class 有什麼區別,他們不都是型別嗎? 其實答案就是這兩者在 python3 中並沒有區別,可以將他們看做一個東西。
def main(): x = int() print(f'{x=}') B = type('B',(),{}) print(f'{B=}') if __name__ == "__main__": main()
不過如果進一步深入研究,兩種 class 和 type 在字面上,是不同兩樣東西,class 作為關鍵字來定義型別時,是呼叫其構造器來做了一些初始化的工作。
def main(): x = int() print(f'{x=}') B = type('B',(),{}) print(f'{B=}') if __name__ == "__main__": main()
我們可以這樣來定義一個型別
x=0 B=<class '__main__.B'>
可以用 class 方式來定義一個類 A,然後我們在用 type 方式來建立一個類,type 接受 3 個引數分別是類的名稱,這裡接受的字串型別的名稱、以及該類的基礎類別,是組元的形式,接下來是就是一個屬性,屬性是字典形式資料,鍵是屬性名稱,值是屬性值。
class A: a = 2 b = 'hello' def f(self): return 12
下面我們用 make_A
來建立一個類, 這裡使用 type 來定義一個類
def make_A(): name = 'A' bases = () a = 2 b = 'hello' def f(self): return 12 namespace = {'a':a,'b':b,'f':f} A = type(name,bases,namespace) return
通過 type 建立類時候需要傳入類名稱 A 然後 base 是一個要建立類 A 的基礎類別,namescpace 是類屬性,是 dict 形式,鍵是屬性名稱,而值是屬性值。
def make_A_more_accurate(): name = 'A' bases = () namespace = type.__prepare__(name,bases) body = ( """ a = 1 b = 'hello' def f(self): return 12 """ ) exec(body,globals(),namespace) A = type(name,bases,namespace) return A
metaclass 是繼承於 type,那麼 metaclass 的工作也是用於建立 class,我們可以在 metaclass 中做一些自定義的事情,
這裡可能比較難理解是 __prepare__
上網找到關於 __prepare__
解釋,暫時說一下自己認識,可能有點淺,感覺就是為類建立了一個區域性的作用域。
namespace = type.__prepare__(name,bases) print(namespace)
type.__prepare__
應該是返回一個區域性名稱空間,
exec(body,globals(),namespace)
class Tut: ... tut = Tut() print(f'{type(tut)=}') print(f'{type(Tut)=}')
上面例子定義一個類,然後範例化 Tut 類得到物件 tut,接下來分別輸出 tut 和 Tut 型別
type(tut)=<class '__main__.Tut'> type(Tut)=<class 'type'>
不難看出 tut 是 Tut 的範例,而 Tut 是 type 的物件
class TutMetaClass(type): ... class Tut(metaclass=TutMetaClass): ...
然後我們定義一個 TutMetaClass 繼承於 type,然後將 Tut 類的 metaclass 指向 TutMetaClass ,然後 tut 型別為 Tut,而 Tut 型別為 TutMetaClass 型別
type(tut)=<class '__main__.Tut'> type(Tut)=<class '__main__.TutMetaClass'>
到此這篇關於 python 中的 元類metaclass詳情的文章就介紹到這了,更多相關 python metaclass 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45