元类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

 

posted @ 2018-07-15 13:16  huang99882008  阅读(449)  评论(0)    收藏  举报