元类多重继承不一致
为什么这样:
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
Why is this:
class MyType(type):
def __init__(cls, name, bases, attrs):
print 'created', cls
class MyMixin:
__metaclass__ = MyType
class MyList(list, MyMixin): pass
okay, and works as expected:
created <class '__main__.MyMixin'>
created <class '__main__.MyList'>
But this:
class MyType(type):
def __init__(cls, name, bases, attrs):
print 'created', cls
class MyMixin:
__metaclass__ = MyType
class MyObject(object, MyMixin): pass
Is not okay, and blows up thusly?:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这不是一个自定义元类问题(尽管它是在元类阶段诊断的):
并且问题与此问题相同:
即,不能从基类乘以派生类继承 - - 不可能定义一个一致的 MRO 来满足通常的 MRO 约束/保证。
幸运的是,您不想这样做——子类可能会重写基类的某些方法(这就是普通子类所做的;-),并且具有基类“前面”类意味着“隐藏覆盖”。
将基类放在派生类之后毫无用处,但至少是无害的(并且与正常的 MRO 保证一致)。
您的第一个示例当然有效,因为
MyMixin
不是派生自list
:...但它是派生自
object
(就像每个现代风格的 Python 类一样),因此第二个示例无法工作(与具有自定义元类的MyMixin
完全独立)。It's not a custom-metaclass problem (though it's diagnosed at metaclass stage):
and the problem's just the same as this one:
i.e., can't multiply inherit from a base class followed by a derived class -- it's impossible to define a consistent MRO that satisfies the usual MRO constraints/guarantees.
Fortunately, you don't want to do that -- the subclass presumably overrides some method of the base class (that's what normal subclasses do;-), and having the base class "in front" would mean "shadowing the override away".
Putting the base class after the derived one is pretty useless, but at least it's innocuous (and consistent with normal MRO guarantees).
Your first example of course works because
MyMixin
is not derived fromlist
:...but it is derived from
object
(like every modern-style Python class), so the second example cannot work (quite independently fromMyMixin
having a custom metaclass).这里,你是继承父类,而父类已经继承了另一个类,所以不需要继承父类已经继承的类。
例如:
会抛出错误,因为A继承了Object类,B继承了A,所以B间接继承了object,所以不需要继承object。
。
。
。
解决方案是从 B 类 ... 参数列表中删除对象类。
Here, you are inheriting the parent class, and the parent class is already inheriting another class, so there is no need to inherit the class that the parent class already inherited.
For example:
It will throw an error because A is inheriting the class Object and B is inheriting the A, so indirectly B is inheriting object, so there is no need to inherit object.
.
.
.
The Solution is to just remove the object class from class B ... arguments list.