2014-02-09 86 views
2

我有点困惑元继承的情况下多继承。Python的metaclasses混淆

考虑下面的代码:

class MetaClass1(type): 
    def __init__(cls, name, bases, dict_): 
     print "MetaClass1" 

class MetaClass2(type): 
    def __init__(cls, name, bases, dict_): 
     print "MetaClass2" 

class A(object): 
    __metaclass__ = MetaClass1 


class B(object): 
    __metaclass__ = MetaClass2 

class C(A, B): 
    pass 

的这个输出将是如下:

  1. “MetaClass1”

  2. “MetaClass2”

  3. 类型错误有关元类冲突,这是预期的,没有问题毫秒关于这一点。

接下来我会改变一下代码并执行以下操作:

class MetaClass1(type): 
    def __init__(cls, name, bases, dict_): 
     print "MetaClass1" 

class MetaClass2(MetaClass1): 
    def __init__(cls, name, bases, dict_): 
     print "MetaClass2 inherits" 
     super(MetaClass2, cls).__init__(name, bases, dict_) 

class A(object): 
    __metaclass__ = MetaClass1 


class B(object): 
    __metaclass__ = MetaClass2 

class C(A, B): 
    pass 

这一次的输出将是:

  1. “MetaClass1”

  2. “MetaClass2继承”

    “MetaClass1”

  3. “MetaClass2继承”

    “MetaClass1”

C类的MRO是:

[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>] 

为什么C类接收MetaClass2作为其元类而不是MetaClass1?

回答

5

当决定一个没有明确指定的类的元类时(例如你的C),Python检查正在创建的类的所有超类(直接和间接)的元类,并选择一个元类是所创建类的所有超类的所有元类的子类型。如果没有这样的元类,它会产生一个TypeError

在你的例子中,MetaClass2是继承自C的所有超类的元类的一个元类。

这涵盖在section 3.3.3.1的语言参考。

+0

谢谢! 这实际上是一个非常聪明的机制。 – Nadav