那么类也是对象,它又是谁实例化得到的呢?
结论1:元类就是产生类的类,默认情况下type就是所有类的元类
0|1二、不依赖于class关键字创建类
根据第一个结论我们能理出两条对应关系
1.调用元类得到自定义的类
2.调用自定义的类得到自定义的类的对象
现在我们来看第一对关系,调用元类来得到自定义的类,都需要哪些参数(OldboyTeacher=type(...),括号内传什么?)
我们自定义一个类的时候都有哪些关键的组成部分:
1.类名
2.类的父类
3.类的名称空间
就以第一阶段的OldboyTeacher类为例,calss关键字创建自定义类的步骤
知识点补充:
如何执行一段字符串内部的代码并将产生的名称空间交给对应的参数? >>> exec()
有了这个exec方法后,我们就可以不依赖于calss关键字创建自定义类
0|1三、自定义元类控制类的创建过程
1.如何自定义元类
2.__call__
思考:一个类的对象加括号调用会执行该对象父类中的__call__方法,那么类也是对象,它在加括号实例化对象的时候,是不是也应该走它父类的__call_方法?
思考:类加括号实例化对象的时候,有哪几个步骤?
1.创建一个该类的空对象
2.实例化该空对象
3.将实例化完成的空对象返回给调用者
那接下来就需要我手动去干这三件事了
思考:这是类加括号产生对象的过程,那么我元类加括号产生类的过程是不是也应该是这个三步
1.产生一个空对象(指类)
2.实例化该空对象(实例化类)
3.将实例化完成的类对象返回
那依据上面的推导,self.__new__就是关键了,我可以在我的自定义元类里面定义一个__new__方法,看看它到底是个啥
我们发现__new__里面的*args参数接收到了三个位置参数,并且很容易辨认它们对应的就是类名,类的父类,类体代码执行后的名称空间
那么我们可不可以将__new__()的形参换一种写法
验证:
结论:
由此我们就可以通过自定义元类,并重写__new__方法来拦截类的创建过程,在类被创建出来之前进行一系列其他操作