使用元类与多重继承结合使用的TypeErrors [英] TypeErrors using metaclasses in conjunction with multiple inheritance

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

问题描述

我有两个有关融合元类和多重继承的问题.第一个是:为什么我为类Derived而不是Derived2收到TypeError?

I have two questions converning metaclasses and multiple inheritance. The first is: Why do I get a TypeError for the class Derived but not for 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

确切的错误消息是:

TypeError: Error when calling the metaclass bases Cannot create a consistent method resolution order (MRO) for bases object, Klass

TypeError: Error when calling the metaclass bases Cannot create a consistent method resolution order (MRO) for bases object, Klass

第二个问题是:为什么super在这种情况下不起作用(如果我使用__init__而不是__new__,则super再次起作用):

The second question is: Why does super not work in this case(if I use __init__ instead of __new__, super works again):

class Metaclass(type):
    def __new__(self, name, bases, dict_):
        return super(Metaclass, self).__new__(name, bases, dict_)

class Klass(object):
    __metaclass__  = Metaclass

我得到了:

TypeError: Error when calling the metaclass bases type.__new__(X): X is not a type object (str)

TypeError: Error when calling the metaclass bases type.__new__(X): X is not a type object (str)

我正在使用Python 2.6.

I'm using Python 2.6.

推荐答案

第二个问题已经被很好地回答了两次,尽管__new__实际上是静态方法,而不是注释中错误声明的类方法...:

The second question has already been well answered twice, though __new__ is actually a staticmethod, not a classmethod as erroneously claimed in a comment...:

>>> class sic(object):
...   def __new__(cls, *x): return object.__new__(cls, *x)
... 
>>> type(sic.__dict__['__new__'])
<type 'staticmethod'>

第一个问题(有人指出)与元类无关:如果B是A的子类,则您不能简单地从A和B的任何两个类中继承继承.

The first question (as somebody noted) has nothing to do with metaclasses: you simply can't multiply inherit from any two classes A and B in this order where B is a subclass of A. E.g.:

>>> 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的(基本上不存在;-)对它的几种特殊方法的定义必须优先于其他类,从而导致其他类的替代被忽略?

The MRO guarantees that leftmost bases are visited before rightmost ones - but it also guarantees that among ancestors if x is a subclass of y then x is visited before y. It's impossible to satisfy both of these guarantees in this case. There's a good reason for these guarantees of course: without them (e.g. in old style classes, which only guarantee the left-right order in method resolution, not the subclass constraint) all overrides in x would be ignored in favor of the definitions in y, and that can't make much sense. Think about it: what does it mean to inherit from object first, and from some other class second? That object's (essentially nonexistent;-) definition of its several special methods must take precedence over the other class's, causing the other class's overrides to be ignored?

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

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