没有在子类中调用元类 [英] Metaclass not being called in subclasses

查看:33
本文介绍了没有在子类中调用元类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆