12

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

在我定义类 XI 之后,期望 Z._new__ 被调用,并打印没有发生的两行(因为元类是继承的?)

4

1 回答 1

14

问题是cls调用时参数(即元类对象)没有传递type,因此Y创建和返回的类对象没有对元类的任何引用Z

如果您将最后一行替换__new__

return super(Z, cls).__new__(cls, name, bases, attrs)

然后它工作。请注意,即使cls使用了 insuper我们仍然必须提供cls作为参数,因为super这里返回一个未绑定的方法(更多信息请参见这里)。

作为使用 super 的替代方法,可以使用:

 return type.__new__(cls, name, bases, attrs)

重要的是我们将cls(我们的元类对象Z)赋予 classmethod __new__。较短的形式自己type(name, bases, attrs)填写参数,这当然是错误的。此错误类似于使用错误参数调用实例方法。typeclsself

我更喜欢使用super,因为这是更好的风格。

于 2009-11-20T14:35:24.837 回答