Python MetaClass元类实现的底层原理
要理解 MetaClass 的底层原理,首先要深入理解 Python 类型模型。本节将从以下 2 点对 Python 类型模型做详细的介绍。
简单来说,当定义一个类时,例如下面语句:
总之,正是 Python 的类创建机制,给了 metaclass 大展身手的机会,即一旦把一个类型 MyClass 设置成元类 MyMeta,那么它就不再由原生的 type 创建,而是会调用 MyMeta 的 __call__ 运算符重载:
换句话说,metaclass 仅仅是给小部分 Python 开发者,在开发框架层面的 Python 库时使用的。而在应用层,metaclass 往往不是很好的选择。
1) 所有的 Python 的用户定义类,都是 type 这个类的实例
事实上,类本身不过是一个名为 type 类的实例,可以通过如下代码进行验证:class MyClass: pass instance = MyClass() print(type(instance)) print(type(MyClass))输出结果为:
<class '__main__.MyClass'>
<class 'type'>
2) 用户自定义类,只不过是 type 类的 __call__ 运算符重载。
当定义完成一个类时,真正发生的情况是 Python 会调用 type 类的 __call__ 运算符。简单来说,当定义一个类时,例如下面语句:
class MyClass: data = 1Python 底层执行的是下面这段代码:
class = type(classname, superclasses, attributedict)其中等号右边的 type(classname, superclasses, attributedict) 就是 type 的 __call__ 运算符重载,它会进一步调用下面这 2 个函数:
type.__new__(typeclass, classname, superclasses, attributedict) type.__init__(class, classname, superclasses, attributedict)以上整个过程,可以通过如下代码进行论证:
class MyClass: data = 1 instance = MyClass() print(MyClass,instance) print(instance.data) MyClass = type('MyClass', (), {'data': 1}) instance = MyClass() print(MyClass,instance) print(instance.data)运行结果为:
<class '__main__.MyClass'> <__main__.MyClass object at 0x000001CB469F7400>
1
<class '__main__.MyClass'> <__main__.MyClass object at 0x000001CB46A50828>
1
总之,正是 Python 的类创建机制,给了 metaclass 大展身手的机会,即一旦把一个类型 MyClass 设置成元类 MyMeta,那么它就不再由原生的 type 创建,而是会调用 MyMeta 的 __call__ 运算符重载:
class = type(classname, superclasses, attributedict) # 变为了 class = MyMeta(classname, superclasses, attributedict)
使用 metaclass 的风险
正如上面所看到的那样,metaclass 这样“逆天”的存在,会"扭曲变形"正常的 Python 类型模型,所以,如果使用不慎,对于整个代码库造成的风险是不可估量的。换句话说,metaclass 仅仅是给小部分 Python 开发者,在开发框架层面的 Python 库时使用的。而在应用层,metaclass 往往不是很好的选择。
建议初学者不要轻易尝试使用 mateclass。
所有教程
- socket
- Python基础教程
- C#教程
- MySQL函数
- MySQL
- C语言入门
- C语言专题
- C语言编译器
- C语言编程实例
- GCC编译器
- 数据结构
- C语言项目案例
- C++教程
- OpenCV
- Qt教程
- Unity 3D教程
- UE4
- STL
- Redis
- Android教程
- JavaScript
- PHP
- Mybatis
- Spring Cloud
- Maven
- vi命令
- Spring Boot
- Spring MVC
- Hibernate
- Linux
- Linux命令
- Shell脚本
- Java教程
- 设计模式
- Spring
- Servlet
- Struts2
- Java Swing
- JSP教程
- CSS教程
- TensorFlow
- 区块链
- Go语言教程
- Docker
- 编程笔记
- 资源下载
- 关于我们
- 汇编语言
- 大数据
- 云计算
- VIP视频