为什么是这样:
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
2 回答
它在元类阶段被诊断为's not a custom-metaclass problem (though it'):
问题和这个问题一样:
即,不能从基类继承乘以派生类 - 不可能定义满足通常的MRO约束/保证的一致MRO .
幸运的是,您不希望这样做 - 子类可能会覆盖基类的某些方法(这是正常的子类所做的;-),并且具有基类"in front"将意味着"shadowing the override away" .
将基类放在派生类之后是没用的,但至少它是无害的(并且与正常的MRO保证一致) .
您的第一个课程示例有效,因为
MyMixin
不是从list
派生的:...但它派生自
object
(与每个现代风格的Python类一样),因此第二个示例无法工作(完全独立于具有自定义元类的MyMixin
) .在这里,您继承父类,并且父类已经继承了另一个类,因此不需要继承父类已经继承的类 .
例如:
它会抛出一个错误,因为A继承了Object类而B继承了A,所以间接B是继承对象,所以不需要继承对象 . . . .
解决方案是从类B ...参数列表中删除对象类 .