元类多重继承不一致 [英] Metaclass multiple inheritance inconsistency

查看:71
本文介绍了元类多重继承不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是为什么:

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'>

但是这个:

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

推荐答案

这不是一个自定义元类问题(尽管在元类阶段已被诊断为 ):

It's not a custom-metaclass problem (though it's diagnosed at metaclass stage):

>>> 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

即,不能将继承自基类的继承乘以派生类的继承-定义一个满足常规MRO约束/保证的一致MRO是不可能的.

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".

将基类放在之后,这是没有用的,但至少它是无害的(并且与常规的MRO保证一致).

Putting the base class after the derived one is pretty useless, but at least it's innocuous (and consistent with normal MRO guarantees).

您的第一个示例当然是有效的,因为MyMixin不是 衍生自list:

Your first example of course works because MyMixin is not derived from list:

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

...但是它 是从object派生的(就像每个现代风格的Python类一样),因此第二个示例无法正常工作(完全独立于具有自定义元类的MyMixin).

...but it is derived from object (like every modern-style Python class), so the second example cannot work (quite independently from MyMixin having a custom metaclass).

这篇关于元类多重继承不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆