元类metaclass(一切都是对象)
Python类哲学:
1、一切都是对象。(everything is object)
2、所有对象object都是由类class实例化出来的。比喻:所有的人(对象)都有自己的妈(类),都是他妈生的。参照上一条,当妈的也是人也有必然有自己的妈。
3、那问题来了,最早的妈是谁,她又是谁生的?
答:人类最早的妈是女娲,但在python里最早的妈名为type,外号metaclass,又称元类。type的妈是谁,还是type,也就是type自己生了自己,type是万物本源。
4、基类object又是什么?
答:基类是所有类的父类,py3中所有的类都默认继承了基类,包括元类type。比喻:所有当妈的都有一个公共的爹,都继承了这个爹的基因。
5、怎么查看类的继承关系,即一个女人如何找到自己的爹?
答:print(类.__mro__)
6、如何通过对象找到创建它的类,即如何找到自己的妈?
答:三种方法,一是用__class__属性,对象.__class__即为创建它的类。二是用isinstance()方法,判断对象和类的关系。三是用type()方法,输出结果与第一种方法类似。
创建类的过程,即class关键字的内含操作,包括四件事:
类的实例化过程,会调用元类中的__call__方法,包括三件事

class People: def __init__(self,name,age): self.name = name self.age = age print('%s今年%d岁了'%(name,age)) def __call__(self, *args, **kwargs): print(self.__dict__,type(self))
这个类里有两个内置方法:__init__,__call__
注:调用对象中含有self形参的方法(对象绑定方法),会自动将对象本身传参给self,不用手动传参。
对象名加括号被调用时即执行其类中的__call__方法。类的实例化,即类名加括号被调用,即调用元类中的__call__方法。
在类的实例化过程中,还有一个非常重要的方法__new__,这个方法的作用是创建一个新的对象。
在元类的__call__方法中,会先后执行__new__和__init__方法。
元类的知识应用:
1、想要修改类的创建规则,即要修改元类的实例化过程,即修改元类中的__init__方法。
#首先要自定义一个新的元类,并重构__init__方法 class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): super().__init__(class_name,class_bases,class_dic) if not '__doc__' in class_dic: raise TypeError('必须有注释') #然后创建类的时候,要用参数指定刚才创建的新元类 class People(object,metaclass=Mymeta): 'asdf' pass
2、想要修改类的实例化规则,即要修改元类中的__call__方法。
#创建一个新的元类,并重构__call__方法 class Mymeta(type): def __call__(self, *args, **kwargs): #1、调用__new__产生一个空对象obj obj=self.__new__(self) # 此处的self是类,必须传参,代表创建一个新的对象obj #生成了obj以后,就可以修改obj.__dict__等,以达到我们的最终目的:修改类的实例化规则。 #2、调用__init__初始化空对象obj self.__init__(obj,*args,**kwargs) #3、返回初始化好的对象obj return obj #定义类的时候指定参数为刚创建的元类 class test(object,metaclass=Mymeta): pass

浙公网安备 33010602011771号