重点分清楚对象是由A类实例化的,A类是由B类实例化的,
调用B类的__call__(self,*args,**kwargs),self=A
__call__()函数中执行
A_obj=self.__new__(self),
self.__init__(A_obj,*args,**kwargs)
return A_obj
示例一:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
示例一: class Mymeta(type): def __init__(self,name,bases,dic): print('===>Mymeta.__init__') def __new__(cls, *args, **kwargs): print('===>Mymeta.__new__') return type.__new__(cls,*args,**kwargs) def __call__(self, *args, **kwargs): #若Foo('eagon'),self 为Foo,*args='egon' print('aaa') obj=self.__new__(self) self.__init__(self,*args,**kwargs) return obj class Foo(object,metaclass=Mymeta): def __init__(self,name): self.name=name def __new__(cls, *args, **kwargs): return object.__new__(cls) ''' 需要记住一点:名字加括号的本质(即,任何name()的形式),都是先找到name的爹,然后执行:爹.__call__ 而爹.__call__一般做两件事: 1.调用name.__new__方法并返回一个对象 2.进而调用name.__init__方法对儿子name进行初始化 ''' ''' class 定义Foo,并指定元类为Mymeta,这就相当于要用Mymeta创建一个新的对象Foo,于是相当于执行 Foo=Mymeta('foo',(...),{...}) 因此我们可以看到,只定义class就会有如下执行效果 ===>Mymeta.__new__ ===>Mymeta.__init__ 实际上class Foo(metaclass=Mymeta)是触发了Foo=Mymeta('Foo',(...),{...})操作, 遇到了名字加括号的形式,即Mymeta(...),于是就去找Mymeta的爹type,然后执行type.__call__(...)方法 于是触发Mymeta.__new__方法得到一个具体的对象,然后触发Mymeta.__init__方法对对象进行初始化 ''' ''' obj=Foo('egon') 的原理同上 ''' ''' 总结:元类的难点在于执行顺序很绕,其实我们只需要记住两点就可以了 1.谁后面跟括号,就从谁的爹中找__call__方法执行 type->Mymeta->Foo->obj Mymeta()触发type.__call__ Foo()触发Mymeta.__call__ obj()触发Foo.__call__ 2.__call__内按先后顺序依次调用儿子的__new__和__init__方法 '''
示例二:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
''' class Mymeta(type): #但凡继承了type的类才能称之为自定义的元类,否则就是只是一个普通的类 pass class Teacher(object): #Teacher=Mymeta('Teacher',(object,),{...}) school = 'Qinghua' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def score(self): print('%s is scoring' %self.name) def __call__(self, *args, **kwargs): print(self) print(args) print(kwargs) tea1=Teacher('egon',18,'male') tea1(1,2,a=1,b=2) #__call__(tea1,(1,2).{'a':1,'b':2}) ''' 总结:对象之所以可以调用,是因为对象的类中有一个函数__call__ 推导:如果一切皆对象,那么Teacher也是一个对象,该对象之所可以调用,肯定是这个对象的类中也定义了一个函数__call__ class Mymeta(type): #但凡继承了type的类才能称之为自定义的元类,否则就是只是一个普通的类 def __call__(self, *args, **kwargs): #self=Teacher这个类,args=('egon',18,'male'),kwargs={} # 1. 先产生一个空对象 tea_obj=self.__new__(self) #tea_obj是Teacher这个类的对象 self--->Teacher # 2. 执行__init__方法,完成对象的初始属性操作 self.__init__(tea_obj,*args,**kwargs) # 3. 返回初始化好的那个对象 return tea_obj class Teacher(object,metaclass=Mymeta): #Teacher=Mymeta('Teacher',(object,),{...}) school = 'Qinghua' #tea_obj,'egon',18,'male' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def score(self): print('%s is scoring' %self.name) tea1=Teacher('egon',18,'male') # 会触发Teacher的类(即元类)中的__call__函数 print(tea1) print(tea1.__dict__)