最近碰到跟這個有關的議題,因此就特別來了解一下,基本上來說 meta class 是class的class,也因此meta有超元的意思,舉例: metaprogram 就有超程式的意思, 產生程式的程式,所以呢!
- class 是 metaclass的 instance屌吧!
- 一般來說 class 的 instance 是一個 object
在python中,class一般的確是拿來創造物件,如下示範
1 | class objectCreator(object): |
但是呢~ 其實在python中,class其實也是個物件!
沒錯! 別懷疑,若你像我一樣從C或C++跳過來用python的,想必會感到很好奇! 這也是動態語言跟靜態語言不太一樣的地方,一般而已動態語言會傾向與任何東西都是物件這種特性,以下來證明!
你可以操作class像是操作物件一樣,
舉例:
- assign 它
- 複製它
- 為它增加屬性
- 把他當作參數一樣傳遞
1 | def printClass(cls): |
試玩了一下證明,的確class可以操作物件那樣被操作,這邊我們就用python的built-in function type,來看看class會跑出什麼資訊 :)
1 | print(type(1)) |
注意到了嗎!!
class的類型是type,這代表著一件事,我們可以用type來創造class。type官方文件
type(name, base, dict) 所以我們來試著用type創造一個class
1 | creature = type('creature', (), {}) |
接著我們讓creature多一個attribute看看
1 | creature = type('creature', (), {'is_alive': True}) |
以上測試用type是可以創造出class的,那麼接著來測試一下繼承
1 | bird = type('bird', (creature, ), {'creature_type':'bird'}) |
前面講了那麼多,其實就要讓你了解,meta class的概念~
In brief, 可以這樣說
IamClass = metaclass()
IamObject = IamClass()
再來就是進入meta
在class裡面若有定義 _metaclass_ 在創建物件時,python會先進入這邊,做一些初始動作 詳情可以看這邊
簡單來說就是,python平常是用自定義的type來創造class,藏在背後,若你想要改變創造class的行為,換句話說就是你想要用你自創的type來創造 class,那你就要定義 _metaclass_,python會去抓你有沒有定義,有的話就會去用你定義的type來取代原生type~
相關文檔
基本上,type只要是一個callable物件即可,但是他要接受3個參數和回傳一個物件
以下舉個例子!
1 | def mymeta(name, base, attributes): |
再來做個有趣的實驗,常常會有個情形,再開發專案我們常常想要知道哪個函式,在什麼時候有被call的,這時候若利用metaclass,會達到相當方便的妙用! 以下示範
1 | import time |
上面利用metaclass,做到每個callable attribute,將會被logged起來
再來看看其他user case,也是個人我目前想要試的功能,”真”動態創造class,概念上來說,就是一個class factory,假設我給予一個identifier,然後根據identifier 創造出相對應的class。
如果不用metaclass,可能就要用一堆十分不好看的if else去判斷,除了代碼hedious之外,日後要維護跟用metaclass比較起來也沒那麼順手 :)
ex.
1 | class Iskill: |
之後給予factory相對應的參數,就會創造出你定義的相對class,以下示範
1 | class SkillFactory(object): |
目前我認識就大概到這邊,以後若有其他更有趣的用法,會再上來PO一篇的。目前要學的東西可多了,只是我好像都在學一些不是職場上頗重要的東西,我時常在想自己這樣是不是很呆,或是說浪費時間,自從出了社會後,我內心的交雜其實更嚴重了,有許多矛盾的事情一直在我心中盤繞,sigh…. 原本以為早點出社會後,許多事情或許會茅塞頓開,但現在看來並非如此,反而陷入了更加社會現實面的問題,或許我需要一點時間來適應和冷靜吧~