Python文档说metaclass of a class can be any callable。我看到的所有示例都使用一个类。为什么不使用功能?它是可调用的,并且定义起来非常简单。但这是行不通的,我也不知道为什么。
这是我的代码:
class Foo(object):
def __metaclass__(name, base, dict):
print('inside __metaclass__(%r, ...)' % name)
return type(name, base, dict)
print(Foo.__metaclass__)
class Bar(Foo):
pass
print(Bar.__metaclass__)
这是输出:
inside __metaclass__('Foo', ...)
<unbound method Foo.__metaclass__>
<unbound method Bar.__metaclass__>
元类方法是为父类和子类定义的。为什么只为 parent 打电话呢? (是的,我尝试为我的元类使用classmethod和staticmethod装饰器,但均无效。是的,这似乎是Metaclass not being called in subclasses的dup,但它们作为元类是一个类,而不是一个函数。)
最佳答案
答案在precedence rules for __metaclass__
lookup中:
如果我们检查Foo.__class__
,我们会发现它是<type 'type'>
,它可以作为您的名为type
的元类函数构造Foo
。__class__
将type
设置为type.__new__
的第一个参数,这就是为什么在类元类中我们将type.__new__(cls, name, bases, dict)
(或super(Metaclass, cls).__new__(cls, ...)
)称为。但是,如果元类是一个函数,我们将无法做到这一点:
>>> def __metaclass__(name, base, dict):
>>> print('inside __metaclass__(%r, %r, %r)' % (name, base, dict))
>>> return type.__new__(__metaclass__, name, base, dict)
>>> class Foo(object):
>>> __metaclass__ = __metaclass__
TypeError: Error when calling the metaclass bases
type.__new__(X): X is not a type object (function)
同样,如果我们尝试将Foo.__class__
设置为您的__metaclass__
,则会失败,因为__class__
属性必须是一个类:>>> Foo.__class__ = Foo.__metaclass__.__func__
TypeError: __class__ must be set to new-style class, not 'function' object
因此,使元类类继承type
而不是可调用对象的原因是使它们可继承。关于python - 为什么没有为子类调用我的元类函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25405401/