nil*_*ils 4 python metaclass multiple-inheritance python-2.x
我有两个问题,即转换元类和多重继承.第一个是:为什么我会为类获取TypeError Derived而不是Derived2?
class Metaclass(type): pass
class Klass(object):
__metaclass__ = Metaclass
#class Derived(object, Klass): pass # if I uncomment this, I get a TypeError
class OtherClass(object): pass
class Derived2(OtherClass, Klass): pass # I do not get a TypeError for this
Run Code Online (Sandbox Code Playgroud)
确切的错误消息是:
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution order (MRO) for bases object, Klass
第二个问题是:为什么super不能在这种情况下工作(如果我使用__init__的替代__new__,super再次工作):
class Metaclass(type):
def __new__(self, name, bases, dict_):
return super(Metaclass, self).__new__(name, bases, dict_)
class Klass(object):
__metaclass__ = Metaclass
Run Code Online (Sandbox Code Playgroud)
在那里我得到:
TypeError: Error when calling the metaclass bases type.__new__(X):
X is not a type object (str)
我正在使用Python 2.6.
第二个问题已经两次得到很好的回答,虽然__new__实际上是一种静态方法,而不是评论中错误地声称的类方法......:
>>> class sic(object):
... def __new__(cls, *x): return object.__new__(cls, *x)
...
>>> type(sic.__dict__['__new__'])
<type 'staticmethod'>
Run Code Online (Sandbox Code Playgroud)
第一个问题(正如有人指出的那样)与元类无关:你根本无法在这个顺序中从任何两个类A和B中继承,其中B是AEg的子类:
>>> class cis(sic): pass
...
>>> class oops(sic, cis): 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 sic, cis
Run Code Online (Sandbox Code Playgroud)
MRO保证在最右边的基地之前访问最左边的基地 - 但它也保证在祖先中如果x是y的子类,则在y之前访问x.在这种情况下,不可能满足这两种保证.当然,这些保证有充分的理由:没有它们(例如在旧式类中,只保证方法解析中的左右顺序,而不是子类约束)x中的所有覆盖都将被忽略,以支持y中的定义,这没有多大意义.想想看:从第一个继承,从第二个阶段继承是什么意思object?这object是(基本上不存在;-)其几个特殊方法的定义必须优先于其他类,导致其他类的覆盖被忽略?