2

我收到错误:TypeError: __init__() 恰好需要 2 个参数(给定 3 个)

当试图从类 Top 实例化一个对象时:

super(Middle1, self).__init__(name, "middle")

class Base(object):
    def __init__(self, name, type):
        pass

class Middle1(Base):
    def __init__(self, name):
        super(Middle1, self).__init__(name, "middle1")

class Middle2(Base):
    def __init__(self, name):
        super(Middle2, self).__init__(name, "middle2")

class Middle3(Base):
    def __init__(self, name):
        super(Middle3, self).__init__(name, "middle3")

class Top(Middle1, Middle2, Middle3):
    def __init__(self):
        super(Top, self).__init__("top")

# Here is where it produces the error
if __name__ == '__main__':
    Top()

我对这个多重继承问题不了解什么?

注意:这是python 2.7

编辑

好的,所以我尝试了一些我认为适合我的情况的方法。这是等效的最终结果,我认为它基本上是通过不调用 super 而是调用每个单独的 __init__ 来强制深度首先。

class Base(object):
    def __init__(self, name, type):
        pass

class Middle1(Base):
    def __init__(self, name, type = "middle1"):
        super(Middle1, self).__init__(name, type)

class Middle2(Base):
    def __init__(self, name, type = "middle2"):
        super(Middle2, self).__init__(name, type)

class Middle3(Base):
    def __init__(self, name, type = "middle3"):
        super(Middle3, self).__init__(name, type)

class Top(Middle1, Middle2, Middle3):
    def __init__(self):
        Middle1.__init__(self, "top")
        Middle2.__init__(self, "top")
        Middle3.__init__(self, "top")

# No errors anymore
if __name__ == '__main__':
    Top()
4

2 回答 2

4

首先,您必须查看的方法解析顺序Top

>>> for c in Top.__mro__: print c
...
<class '__main__.Top'>
<class '__main__.Middle1'>
<class '__main__.Middle2'>
<class '__main__.Middle3'>
<class '__main__.Base'>
<type 'object'>

这可以帮助您查看每个调用super代表哪个类。

您的错误是认为对的调用super(Middle1, self)指的是(唯一)基BaseMiddle1. 不是:它指的是Middle1.MRO 中的以下类self.__class__。因为self.__class__is Top,下一个类是Middle2__init__它只接受一个参数。

要从方法super中正确使用,您需要确保该方法在每个类中采用相同的参数,因为您无法通过查看代码本身来预测将调用哪个类的方法;它完全取决于启动调用链的对象的类型,这可能是您甚至还不知道的类。

我建议阅读两篇文章:

它们一起让您很好地了解何时super可以正确使用以及如何避免您在此处看到的问题。

(完全披露,我最近没有读过任何一篇文章,所以我不会试图总结每篇文章中提出的建议。)

于 2017-03-10T01:28:46.067 回答
0

您究竟是如何实例化 Top 对象的?

鉴于您上面的代码,以下工作正常:

   topObj = Top()
   middleObj = Middle("middle")
   baseObj = Base("base", "type")
于 2017-03-09T17:41:30.003 回答