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函数

相关文章
相关标签/搜索