没有在子类中调用元类 [英] Metaclass not being called in subclasses
问题描述
这是一个python会话.
Here is a python session.
>>> 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 是继承的?)
After I define class X I expect Z._new__ to be called for it, and to print the two line, which is not happening, (as metaclass are inherited?)
推荐答案
问题是调用type
时未传递cls
参数(它是元类对象),因此类对象Z
的任何引用.
The problem is that the cls
argument (which is the metaclass object) is not passed on when you call type
, therefore the class object Y
that is created and returned does not have any reference to the metaclass Z
.
如果将__new__
中的最后一行替换为
If you replace the last line in __new__
with
return super(Z, cls).__new__(cls, name, bases, attrs)
然后它起作用.请注意,即使在super
中使用了cls
,我们仍然必须同时提供cls
作为参数,因为super
此处返回的是未绑定方法(请参见
then it works. Note that even though cls
is used in super
we still have to provide cls
as an argument as well, since super
here returns an unbound method (see here for more).
作为使用超级人的替代方法,可以使用:
As an alternative to using super one could use:
return type.__new__(cls, name, bases, attrs)
重要的是我们将cls
(我们的元类对象Z
)提供给类方法__new__
.较短的格式type(name, bases, attrs)
会为cls
参数填写type
本身,这当然是错误的.此错误类似于使用错误的self
参数调用实例方法.
The important thing is that we give cls
(our metaclass object Z
) to the classmethod __new__
. The shorter form type(name, bases, attrs)
fills in type
itself for the cls
argument, which is of course wrong. This error is similar to calling an instance method with the wrong self
argument.
我更喜欢使用super
,因为这是更好的样式.
I prefer using super
, since this is better style.
这篇关于没有在子类中调用元类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!