python 的 metaclass

Python 是一種很是靈活的語言,這使得它具備很強的表達力,metaclass 也是這種強大表達力的一個體現。python

啥是 metaclass 呢? meta- 這個詞彷佛這些年愈來愈流行,翻譯成中文,通常是  元..., 好比元認知,元數據。「元什麼」 通常表示的含義是 什麼的什麼, 元數據即數據的數據,元認知即認知的認知。metaclass 就是類的類。粗略的說,執行一個 metaclass 會獲得一個新的 class, Python 內置的 type 就能夠當作一個metaclass。web

metaclass 有什麼用呢?這個問題的答案和另外一個問題的答案其實有些相似: decorator 有什麼用呢? metaclass 和 decorator 都屬於元編程。元編程,能夠理解爲讓程序來寫程序。固然,這裏說的不是人工智能來寫程序啊,只是一種固定模式的程序轉換。讓程序來寫程序的目的,我感受常見的通常是三個:一是減小重複性的 boilerplate, 這方面最典型的例子是 C 語言裏的宏;第二是提供簡潔易用的用戶接口,好比python web 框架 Falsk 裏面的裝飾器 @app.route, 你不用它,也能夠註冊 url endpoint, 可是不如這個簡潔;第三,一段代碼的邏輯是動態的,可是一旦初始化完成以後代碼邏輯就能夠肯定了,也很適合使用元編程,好比,一個函數內部兩種邏輯,選擇哪一種依賴程序的某個配置,這個配置在編碼階段沒法肯定,可是一旦程序啓動讀取了配置以後,這個配置也是不會變的,這時就可使用裝飾器來動態定義該函數。編程

Python 中的 decorator 是能夠裝飾 class的, 那爲何還須要 metaclass 呢。PEP 3115 裏作了解釋, decorator 屬於一種後處理,對一個類定義能施加的影響其實頗有限,而metaclass 會深度介入一個類的建立過程。app

metaclass 如何影響一個類的建立

python 官方的 Language Reference 中的 Data model一章有詳細的說明,此處簡單轉述一下原理(忽略了一些細節)。框架

  1. 肯定一個類的 metaclass, 若是一個類在定義時顯示指定了 metaclass, 則使用該 metaclass, 不然使用 type() 做爲其metaclass
  2. 準備namespace, 這個 namespace 是類內部的 namespace, 是一個相似字典的對象,用於保存類的各類屬性。這個 namespace 是經過 metaclass.__prepare__(name, bases, **kwds) 獲得。
  3. 在上述 namespace 中執行被定義的類的 body。
  4. 調用 metaclass(name, bases, namespace, **kwds) 建立被定義的類。

metaclass 示例

可參考 PEP3115 中的示例: https://www.python.org/dev/peps/pep-3115/#example函數

相關文章
相關標籤/搜索