元类 :
如果一切皆对象,而调用一个类,会实例化出一个对象,那把类看做一个对象,这个类A也就是调用了一个另一个类B而生成的对象,另一个类B就叫做元类。类A=类B(....)
- Type(默认为所有类的元类)
在之前,我们可以通过type来确定一个对象的所属类型(即这个对象所属类):
如print(type(1))>>>>>>>>> <class ‘int’> ——— 1 是属于int这个类的。
实际相对于调用type元类传入参数1,生成一个int类。
那么类A是属于哪个类呢:print(type(A))>>>>>> <class ‘type’>
说明类A这个对象是属于type这个类的。即默认元类为type(内置的元类)。元类可以简称为类所属的类,即类的类。
- class关键字创建类的流程分析:
class关键字定义的类本身也是一个对象。负责产生该对象的类称为元类。
Class关键字在创建类的时候,必然调用了内置元类type。即type( )
传入的参数又是什么呢?必然是:
- 类名2.基类们 (元组)
3.类的名称空间(字典):类的名称在执行类体代码而得到,调用type时会依次传入以上三个参数。
综上所述:class创建类的流程为:
1.拿到类名>>2.拿到类的基类们(元组)>>3.执行类体代码体,拿到类的名称空间(字典)>>4.调用元类得到类。
3.exec(‘python代码’,全局,局部)
第一个参数是包含python代码的字符串,该内置方法会自动执行字符串中的代码,且将产生的名字放到对应的名称空间。如果字符串中没有声明是全局,会默认放到局部空间。
参数二是用来接受全局的名称空间。
参数三是局部名称空间。
必须包含三个参数,否则报错。且参数二参数三是字典类型。
4.重点:
类的产生过程就是调用元类的过程:
类=元类(类名,(基类们,),{名称空间})
自定义一个元类的方式:继承元类type。
可以利用自定义元类(作用):
- 控制类的创建过程。(元类中__init__)
自定义元类中的__init__需要的参数就是类名、基类(元组)、名称空间(字典)是给重用继承type中__init__用的,然后在下面再跟上一些逻辑作为控制(限制、规范)产生的类
- 控制生成类的调用。(元类中__call__)
那么调用类实际上是调用元类中的__call__。
以上是__call__的模板(可添加其他限制。)