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/

10-12 20:24