Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将元类与多重继承结合使用时出现的类型错误_Python_Multiple Inheritance_Python 2.x_Metaclass - Fatal编程技术网

Python 将元类与多重继承结合使用时出现的类型错误

Python 将元类与多重继承结合使用时出现的类型错误,python,multiple-inheritance,python-2.x,metaclass,Python,Multiple Inheritance,Python 2.x,Metaclass,我有两个关于聚合元类和多重继承的问题。第一个问题是:为什么类Derived会出现TypeError,而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): p

我有两个关于聚合元类和多重继承的问题。第一个问题是:为什么类
Derived
会出现TypeError,而
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:调用元类基时出错
无法为基本对象Klass创建一致的方法解析顺序(MRO)

第二个问题是:
super
在这种情况下为什么不起作用(如果我使用
\uuuuuu init\uuuuuuuuuuuu
而不是
\uuuuuu new\uuuuuuuu
super
再次起作用):

我得到了:

TypeError:调用元类基类型时出错。\uuuu new\uuuux:
X不是类型对象(str)


我正在使用Python2.6。

对于第一个问题,请看一看“坏方法解析顺序”部分。本质上,这是因为python不知道是使用object还是Klass的方法。(这与元类的使用无关。)

对于第二个问题,您似乎误解了
\uuuu new\uuu
函数的工作原理。它不把对自身的引用作为第一个参数,而是引用被实例化的类的类型。因此,您的代码应该如下所示:

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

class Klass(object):
    __metaclass__  = Metaclass

对于第二个问题,您需要将self传递给
\uuuu new\uuuu
,如下所示:

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

class Klass(object):
    __metaclass__  = Metaclass

我一时想不起为什么会这样,但我想这是因为
类型。
不是一个绑定方法,因此不会神奇地获得自论证。

第二个问题已经被很好地回答了两次,尽管
\u new\u
实际上是一个静态方法,不是注释中错误声明的classmethod…:

>>> class sic(object):
...   def __new__(cls, *x): return object.__new__(cls, *x)
... 
>>> type(sic.__dict__['__new__'])
<type 'staticmethod'>
类sic(对象): ... def uuu new uuuu(cls,*x):返回对象。uuu new uuuuu(cls,*x) ... >>>类型(原文如此) 第一个问题(正如有人指出的)与元类无关:你不能按照B是A的子类的顺序从任意两个类A和B进行乘法继承。例如:

>>> 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
>>类别CI(sic):通过
... 
>>>类oops(sic、cis):通过
... 
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:调用元类基时出错
无法创建一致的方法解析
基础sic、cis的订单(MRO)
MRO保证最左边的碱基在最右边的碱基之前访问,但它也保证在祖先中,如果x是y的子类,那么x在y之前访问。在这种情况下,不可能同时满足这两种保证。当然,这些保证有一个很好的理由:如果没有它们(例如,在旧式类中,只保证方法解析中的左右顺序,而不是子类约束),x中的所有重写都将被忽略,而代之以y中的定义,这没有多大意义。想想看:首先从
对象
继承,然后从其他类继承意味着什么?对象的几个特殊方法的定义(基本上不存在;-)必须优先于其他类的定义,从而导致忽略其他类的重写?

为什么要这样做

class Derived(object, Klass):
Klass已经从object派生

class Derived(Klass):

在这里是合理的。

\uuuu new\uuuuuu
是一个类方法,不要在那里使用self,这很令人困惑是的,在我使用的代码中,我使用了
cls
或类似的东西,但我遵循了原始海报使用的。有意义,只要我不直接从对象继承(这实际上没有什么意义,但我想确定没有什么奇怪的事情发生)应该没问题:)我想知道使用new而不使用super是否可以保存。@nils,是的
\uuuuuuu new\uuuuuu
可以使用w/o
super
——除非在多重继承的复杂情况下。如果你陷入了复杂的多重继承,
\uuuuuuuuuuuuuuuuuuuuuuu
更为谨慎。