python基础-面向对象(二十七)面向对象进阶(十五)元类(二)__call__,__new__,__init__

 

上次说的,Test(metaclass=Mytype),会调用Mytype的__new__,__init__,其实是先调用Mytype的元类的__call__来实现的。证明看下面

class Mymete(type):
    def __init__(self,*args, **kwargs):
        pass
    def __call__(self, *args, **kwargs):
        print('=====>1')


class Mytype(metaclass=Mymete):
    def __init__(self, *args, **kwargs):
        print('=====>init')

    def __new__(cls, *args, **kwargs):
        print('=====>new')
        obj = super().__new__(cls)  # 调用父类的new
        return obj
    def __call__(self, *args, **kwargs):
        print('=====>call')

class Test(metaclass=Mytype):
    def __init__(self, name):
        pass

 

 执行流程

 

 Test(metaclass=Mytype),也就是Test=Mytype(),生成Test,会先去调用Mytype的元类的__call__..系统默认__call__会先调用Mytype的__new__,生成对象以后,在调用Mytype的__init__,最后返回对象。

 

class Mymete(type):  # 元类必须是继承type
    def __init__(self, *args, **kwargs):
        pass

    def __call__(self, *args, **kwargs):  # self是Mytype
        Mytype_obj = self.__new__(self)
        self.__init__(Mytype_obj, *args, **kwargs)
        return Mytype_obj

    ''' 第一步,调用Mytype的__new__,
        第二步,调用Mytype的__init__
        第三步,返回Mytype实例的对象'''


class Mytype(metaclass=Mymete):  # self是Test
    def __init__(self, x, y, z):
        if not x.istitle():  # 对首字母判断后在初始化
            raise TypeError('首字母没大写')
        self.name = x

    def __new__(cls, *args, **kwargs):
        obj = super().__new__(cls)  # 调用父类的new
        return obj

    def __call__(self, *args, **kwargs):
        print('=====>call')


class test(metaclass=Mytype):
    def __init__(self, name):
        pass

 

posted @ 2020-12-18 23:39  枫叶学python  阅读(133)  评论(0)    收藏  举报