__metaclass__
属性不会被继承。但事实上,我在Python中尝试过:
class Meta1(type):
def __new__(cls, clsname, bases, dct):
print "Using Meta1"
return type.__new__(cls, clsname, bases, dct)
# "Using Meta1" printed
class Foo1:
__metaclass__ = Meta1
# "Using Meta1" printed
class Bar1(Foo1):
pass
如预期的那样,Foo
和Bar
都使用Meta1
作为元类,并按预期打印字符串。
但在下面的示例中,当返回type(...)
而不是type.__new__(...)
时,元类不再被继承:
class Meta2(type):
def __new__(cls, clsname, bases, dct):
print "Using Meta2"
return type(clsname, bases, dct)
# "Using Meta2" printed
class Foo2:
__metaclass__ = Meta2
# Nothing printed
class Bar2(Foo2):
pass
检查 __metaclass__
和 __class__
属性,我可以看到:
print Foo1.__metaclass__ # <class '__main__.Meta1'>
print Bar1.__metaclass__ # <class '__main__.Meta1'>
print Foo2.__metaclass__ # <class '__main__.Meta2'>
print Bar2.__metaclass__ # <class '__main__.Meta2'>
print Foo1.__class__ # <class '__main__.Meta1'>
print Bar1.__class__ # <class '__main__.Meta1'>
print Foo2.__class__ # <type 'type'>
print Bar2.__class__ # <type 'type'>
总之:
基类中的
__metaclass__
和__class__
属性都将被继承。Meta2
定义的创建行为将用于Foo2
,尽管Foo2.__class__
实际上是type
。Bar2
中的__metaclass__
属性是Meta2
,但不会影响Bar2
的创建行为。换句话说,Bar2
使用type
作为其 "真正的" 元类,而不是Meta2
。
这些观察结果使我对 __metaclass__
的继承机制有点模糊。
我的猜测是:
当直接将一个类(如
Meta1
)赋值给另一个类 'Foo1' 的__metaclass__
属性时,它是__metaclass__
属性生效。当子类在定义时没有显式设置
__metaclass__
属性时,基类的__class__
属性而不是__metaclass__
属性将决定子类的 "真正" 元类。
我的猜测正确吗?Python 如何处理元类的继承?