我有两个关于转换元类和多重继承的问题。第一个是:为什么我得到类 Derived
而不是 Derived2
的 TypeError?
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
准确的错误信息是:
TypeError:调用元类基础时出错
无法为基础对象 Klass 创建一致的方法解析顺序 (MRO)
第二个问题是:为什么 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
我得到:
TypeError:调用元类基 type.__new__(X) 时出错:
X 不是类型对象 (str)
我正在使用 Python 2.6。
最佳答案
第二个问题已经回答了两次了,虽然__new__
其实是一个staticmethod,而不是评论中错误声称的classmethod...:
>>> class sic(object):
... def __new__(cls, *x): return object.__new__(cls, *x)
...
>>> type(sic.__dict__['__new__'])
<type 'staticmethod'>
第一个问题(正如有人指出的)与元类无关:您不能简单地从任何两个类 A 和 B 中按此顺序乘法继承,其中 B 是 A 的子类。例如:
>>> 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
MRO 保证最左边的碱基在最右边的碱基之前被访问——但它也保证在祖先中如果 x 是 y 的子类,那么 x 在 y 之前被访问。在这种情况下不可能同时满足这两个保证。这些保证当然有一个很好的理由:没有它们(例如,在旧式类中,它只保证方法解析中的左右顺序,不是子类约束)所有 x 中的重写都将被忽略赞成 y 中的定义,这没有多大意义。想一想:首先从 object
继承,然后从其他类继承是什么意思? object
(本质上不存在;-)对其几个特殊方法的定义必须优先于其他类的定义,从而导致其他类的重写被忽略?
关于python - 结合多重继承使用元类的类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2203947/