什么是元类
在Python中“万物”皆是对象,当然类也是对象。
通过类我们可以创建实例对象:
class A: |
那么通过什么我们创建类呢?答案是元类。
即:类是元类的实例
class A: |
元类的作用
元类可以定制化类的创建过程。例如修改类的属性、方法,添加新的属性、方法,甚至可以拦截类的创建过程。
使用type创建类
type
既可以判断对象的类型
type(123) # <class 'int'> |
也是所有类的顶层元类
print(type(int)) # <class 'type'> |
也可以通过type(name, bases, attrs)
动态创建类,
其中,
name
:类的名字;bases
:类继承的父类集合attrs
:类的属性、方法字典
class Person1: |
在这个例子中,Person2和Person1的效果一模一样,因为Python解释器在读到class Person1
的定义时就是调用的type。因此通过Person2创建实例:
p = Person2('John') |
自定义元类
所有类默认情况下,元类是type,当然也可以指定类的元类(当然了,所有类的元类最终都指向了type)
class AMetaClass(type): |
这个例子中A的元类是AMetaClass。
我们知道,创建一个实例对象,会调用类的__new__
方法。同样的,创建一个类,会调用其元类的__new__
方法。因此在元类中重写__new__
方法即可拦截类的生成方式。
class AMetaClass(type): |
那么这样做的意义是什么?
通常来讲,对于普通开发者,并不需要元类编程。但凡事总有例外。
元类编程的最大作用之一,是可以开发框架。
使用元类创建简单的ORM框架
这里使用元类创建简单的ORM框架作为案例。
我希望对于自定义继承自BaseModel的类,其包含一个类变量table_name
,变量名为小写的类名。
class User(BaseModel): |
这里就要用到元类,我们要拦截BaseModel类的生成,在生成其子类的时候给它添加属性table_name,因此完整的代码是:
class ModelMetaClass(type): |