Python 2 中对 type.__init__ 的混淆
A confusion on type.__init__ in Python 2
看看下面的例子
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...
我对这个结果感到很困惑,
- 为什么
Base.__init__
被调用为 D2
,即使我们还没有创建 D2
的实例?
- 既然
Base.__init__
被调用 D2
,为什么 D1
不被调用?
Base.__init__
第一次被调用时:
M = Base('M', (object,), {})
您正在创建 Base
的实例,因此它的 __init__
方法被调用,不足为奇。
创建D2
时第二次调用,因为创建class调用了metaclass[=36的__init__
方法=](是的,class 的 class)是 Base
; D2
是 Base
.
的实例
不为 D1
调用,因为 D1
是 Base
的 subtype/subclass 而不是它的实例。
注意当您将 Base
设为 D1
的元 class 而不是它的超级 class 时会发生什么:
class D1(object):
__metaclass__ = Base
pass
# Base.__init__() with cls <class 'D1'>, name D1...
看看下面的例子
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...
我对这个结果感到很困惑,
- 为什么
Base.__init__
被调用为D2
,即使我们还没有创建D2
的实例? - 既然
Base.__init__
被调用D2
,为什么D1
不被调用?
Base.__init__
第一次被调用时:
M = Base('M', (object,), {})
您正在创建 Base
的实例,因此它的 __init__
方法被调用,不足为奇。
创建D2
时第二次调用,因为创建class调用了metaclass[=36的__init__
方法=](是的,class 的 class)是 Base
; D2
是 Base
.
不为 D1
调用,因为 D1
是 Base
的 subtype/subclass 而不是它的实例。
注意当您将 Base
设为 D1
的元 class 而不是它的超级 class 时会发生什么:
class D1(object):
__metaclass__ = Base
pass
# Base.__init__() with cls <class 'D1'>, name D1...