子类中未调用元类
这里是一个Python的会话。
>>> class Z(type):
def __new__(cls, name, bases, attrs):
print cls
print name
return type(name, bases, attrs)
...
>>> class Y(object):
__metaclass__ = Z
...
<class '__main__.Z'>
Y
>>> class X(Y):
... pass
...
>>> class W(Y):
... __metaclass__ = Z
...
<class '__main__.Z'>
W
>>>
在我定义了类X之后,我期待Z._new__这个方法会被调用,并且打印出两行内容,但实际上并没有发生,(是因为 metaclass会被继承吗?)
1 个回答
14
问题在于,当你调用 type
时,cls
这个参数(也就是元类对象)没有被传递过去。因此,创建并返回的类对象 Y
并没有任何关于元类 Z
的引用。
如果你把 __new__
中的最后一行替换成
return super(Z, cls).__new__(cls, name, bases, attrs)
那么就能正常工作了。需要注意的是,尽管在 super
中使用了 cls
,我们仍然需要把 cls
作为参数提供,因为这里的 super
返回的是一个未绑定的方法(想了解更多可以查看这里)。
作为使用 super
的替代方案,你也可以使用:
return type.__new__(cls, name, bases, attrs)
重要的是,我们需要把 cls
(我们的元类对象 Z
)传递给类方法 __new__
。更简短的形式 type(name, bases, attrs)
会把 type
自身填入 cls
参数,这显然是错误的。这个错误就像用错误的 self
参数调用实例方法一样。
我更喜欢使用 super
,因为这样更符合编程风格。