Python 2中类型.__ init__的混淆

时间:2017-04-21 14:37:39

标签: python python-2.x metaclass

看一下以下示例

class Base(type):
    def __init__(cls, name, bases, dict_):
        print 'Base.__init__() with cls %s, name %s...' % (cls, name, )
        type.__init__(cls, name, bases, dict_)

M = Base('M', (object,), {})

class D1(Base):
    pass

class D2(M):
    pass

输出

Base.__init__() with cls <class '__main__.M'>, name M...
Base.__init__() with cls <class '__main__.D2'>, name D2...

我对结果感到很困惑,

  1. Base.__init__调用D2为什么,即使我们没有创建D2的实例?
  2. Base.__init__调用D2后,为什么D1没有?

1 个答案:

答案 0 :(得分:2)

当你这样做时,第一次调用

Base.__init__

M = Base('M', (object,), {})

您正在创建Base的实例,因此调用其__init__方法,这并不奇怪。

创建D2时第二次调用它,因为创建一个类会调用元类__init__方法(是的,类的类)Base 1}}; D2Base的实例。

D1不会调用它,因为D1Base的子类型/子类,而不是Base的实例。

注意当D1元类class D1(object): __metaclass__ = Base pass # Base.__init__() with cls <class 'D1'>, name D1... 而不是其超类时会发生什么:

{A B C}