元类多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 …参数列表中删除对象类。