元类的 “__call__” 和产品类的 “__init__”

问题描述:

说我有一个元类:元类的 “__call__” 和产品类的 “__init__”

class Meta(type): 
    def __call__(cls, *args): 
     print "Meta: __call__ with", args 

class ProductClass(object): 
    __metaclass__ = Meta 
    def __init__(self, *args): 
     print "ProductClass: __init__ with", args 

p = ProductClass(1) 

输出如下:

Meta: __call__ with (1,) 

问:

为什么不ProductClass的__init__已触发? 仅仅因为Meta的__call__

UPDATE:

现在,我想补充__new__为ProductClass:

class ProductClass(object): 
     __metaclass__ = Meta 
     def __new__(cls, *args): 
      print "ProductClass: __new__ with", args 
      return super(ProductClass, cls).__new__(cls, *args) 
     def __init__(self, *args): 
      print "ProductClass: __init__ with", args 

p = ProductClass(1) 

它是多彩的__call__的责任,呼吁ProductClass的__new____init__

是的 - 这是Meta.__call__拨打ProductClass.__init__(或不是,视情况而定)。

引述documentation

例如限定元类 定制__call__()方法允许自定义行为当类被调用时,例如并不总是 创建一个新的实例。

该页面还提到一种情况,元类的__call__可能会返回一个不同的类的实例(即不ProductClass在你的例子)。在这种情况下,自动呼叫ProductClass.__init__显然不合适。

+0

什么,如果我得到了一个ProductClass“__new__”? Meta的“__call__”调用ProductClass的“__new__”和“__init__”?看我的更新。 – Alcott

+0

显然,Meta的“__call__”在ProductClass的“__new__”之前被首先调用。 – Alcott

+0

问题是,需要'Meta .__ call__'来调用'ProductClass .__ new__'和'ProductClass .__ init__'。通常,'type .__ call__'是为你做的,但是当你定义'Meta .__ call__'时,你会覆盖这个行为,这意味着除非你这么做,否则它不会被执行。所以,你需要自己调用'__new__'和'__init__',或者调用类似'.__ call __(cls,* args)'的东西。 –

有延伸的方法和覆盖它,你只是在你的元类Meta没有叫,因为你定义了__call__方法和你没有调用父__call__首要之间的OOP的差异。有你想你必须扩展__call__方法通过调用父类的方法行为:

class Meta(type): 
    def __call__(cls, *args): 
     print "Meta: __call__ with", args 
     return super(Meta, cls).__call__(*args)