多重继承并调用super()

时间:2017-03-09 17:23:21

标签: python python-2.7 inheritance multiple-inheritance multiple-arguments

我收到错误: 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

修改

好的,所以我尝试了一些我觉得适用于我的情况的东西。这是平等的最终结果,我认为它基本上是通过不调用超级并且调用每个__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()

2 个答案:

答案 0 :(得分:3)

首先,您必须查看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)的调用是指Base的(仅)基类Middle1。它没有:它指的是Middle1的MRO中self.__class__之后的类。由于self.__class__Top,因此行中的下一个类为Middle2,其__init__只接受一个参数。

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

我建议阅读两篇帖子:

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

(在完全披露中,我最近没有阅读任何帖子,所以我不会试图总结每个帖子中提出的建议。)

答案 1 :(得分:0)

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

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

   topObj = Top()
   middleObj = Middle("middle")
   baseObj = Base("base", "type")