元类未在子类中调用
这是一个 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__ 被调用,并打印这两行,但这没有发生,(因为元类是继承的?)
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
>>>
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?)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题是,当您调用
type
时,cls
参数(即元类对象)不会传递,因此类对象Y
创建并返回没有任何对元类Z
的引用。如果将 __new__ 中的最后一行替换为 则
它可以工作。请注意,即使
super
中使用了cls
,我们仍然必须提供cls
作为参数,因为super
> 这里返回一个未绑定的方法(请参阅此处了解更多信息)。作为使用 super 的替代方法,可以使用:
重要的是我们将
cls
(我们的元类对象Z
)赋予类方法__new__
。较短的形式type(name, bases, attrs)
为cls
参数填充type
本身,这当然是错误的。此错误类似于使用错误的self
参数调用实例方法。我更喜欢使用
super
,因为这是更好的风格。The problem is that the
cls
argument (which is the metaclass object) is not passed on when you calltype
, therefore the class objectY
that is created and returned does not have any reference to the metaclassZ
.If you replace the last line in
__new__
withthen it works. Note that even though
cls
is used insuper
we still have to providecls
as an argument as well, sincesuper
here returns an unbound method (see here for more).As an alternative to using super one could use:
The important thing is that we give
cls
(our metaclass objectZ
) to the classmethod__new__
. The shorter formtype(name, bases, attrs)
fills intype
itself for thecls
argument, which is of course wrong. This error is similar to calling an instance method with the wrongself
argument.I prefer using
super
, since this is better style.