Multiple Inheritance and calling super()
I get the error: TypeError: __init__() takes exactly 2 arguments (3 given)
When trying to instantiate an object from the class 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()
What am I not understanding about this multiple inheritance issue?
Note: this is python 2.7
EDIT
Ok so I tried something that I think works for my case. This is the equivelent end result, I think it's basically forcing depth first by not calling super and calling each individual __init__ instead.
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()
First, you have to look at the method resolution order of 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'>
This helps you see which class each call to super
represents.
Your mistake is thinking that the call to super(Middle1, self)
refers to the (only) base class Base
of Middle1
. It does not: it refers to the the class following Middle1
in the MRO of self.__class__
. Since self.__class__
is Top
, the next class in line is Middle2
, whose __init__
takes only one argument.
To use super
correctly from a method, you need to ensure that the method takes the same arguments in every class, because you cannot predict which class's method will be called by looking at the code itself; it depends entirely on the type of the object that initiates the chain of calls, which might be a class you aren't even aware of yet.
There are two posts I suggest reading:
super
. Together, they give you a good understanding of when super
can be used correctly and how to avoid the problem you see here.
(In full disclosure, I haven't read either post recently, so I will refrain from trying to summarize the advice presented in each.)
How exactly are you instantiating Top objects?
Given your code above, the following works fine:
topObj = Top()
middleObj = Middle("middle")
baseObj = Base("base", "type")
链接地址: http://www.djcxy.com/p/26788.html
上一篇: 实时时间序列数据中的峰值信号检测
下一篇: 多重继承和调用super()