元类多inheritance不一致

为什么是这样:

class MyType(type): def __init__(cls, name, bases, attrs): print 'created', cls class MyMixin: __metaclass__ = MyType class MyList(list, MyMixin): pass 

好吧,并按预期工作:

 created <class '__main__.MyMixin'> created <class '__main__.MyList'> 

但是这个:

 class MyType(type): def __init__(cls, name, bases, attrs): print 'created', cls class MyMixin: __metaclass__ = MyType class MyObject(object, MyMixin): pass 

不好吗,这样炸了吗?

 created <class '__main__.MyMixin'> Traceback (most recent call last): File "/tmp/junk.py", line 11, in <module> class MyObject(object, MyMixin): pass TypeError: Error when calling the metaclass bases Cannot create a consistent method resolution order (MRO) for bases object, MyMixin 

这不是一个自定义的元类问题(尽pipe它在元类阶段被诊断出来 ):

 >>> class Normal(object): pass ... >>> class MyObject(object, Normal): pass ... Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Error when calling the metaclass bases Cannot create a consistent method resolution order (MRO) for bases object, Normal 

问题和这个一样:

 >>> class Derived(Normal): pass ... >>> class Ok(Derived, Normal): pass ... >>> class Nope(Normal, Derived): pass ... Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Error when calling the metaclass bases Cannot create a consistent method resolution order (MRO) for bases Normal, Derived 

也就是说,不能从基类和inheritance派生类中inheritance多个inheritance – 不可能定义一个满足通常的MRO约束/保证的一致的MRO。

幸运的是,你不希望这样做 – 子类可能会覆盖基类的某些方法(这是正常的子类所做的 ;-),而将基类“在前面”意味着“遮蔽覆盖”。

将派生类放在派生类之后是相当无用的,但至less它是无害的(并且与正常的MRO保证一致)。

您的第一个课程的例子,因为MyMixin 不是list派生:

 >>> MyMixin.__mro__ (<class '__main__.MyMixin'>, <type 'object'>) 

…但是它object派生的(就像每个现代风格的Python类一样),所以第二个例子不能工作(与MyMixin有一个自定义元类完全独立)。

在这里,您inheritance了父类,并且父类已经inheritance了另一个类,所以不需要inheritance父类已经inheritance的类。

例如:

 class A(object): . . class B(object, A): . . 

它会抛出一个错误,因为A是inheritance类Object而B是inheritanceA,所以间接B是inheritance对象,所以不需要inheritance对象。 。 。 。

解决方法是从类B …参数列表中删除对象类。