[英]Multiple Inheritance and calling super()
I get the error: TypeError: __init__() takes exactly 2 arguments (3 given) 我收到错误:TypeError:__init __()恰好接受2个参数(给定3个)
When trying to instantiate an object from the class Top: 尝试从类Top实例化对象时:
super(Middle1, self).__init__(name, "middle") 超级(中间1,自我)。__init __(名称,“中间”)
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 注意:这是python 2.7
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.
这是等价的最终结果,我认为基本上是通过不调用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()
First, you have to look at the method resolution order of Top
: 首先,您必须查看
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. 这可以帮助您查看每个对
super
调用代表的类。
Your mistake is thinking that the call to super(Middle1, self)
refers to the (only) base class Base
of Middle1
. 你的错误是认为调用
super(Middle1, self)
指(只)基类Base
的Middle1
。 It does not: it refers to the the class following Middle1
in the MRO of self.__class__
. 它不是:它引用
self.__class__
的MRO中Middle1
之后的类。 Since self.__class__
is Top
, the next class in line is Middle2
, whose __init__
takes only one argument. 由于
self.__class__
是Top
,因此下一行是Middle2
,其__init__
仅接受一个参数。
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; 要正确地使用某个方法的
super
方法,您需要确保该方法在每个类中都采用相同的参数,因为您无法通过查看代码本身来预测将调用哪个类的方法。 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
. super
的语义。 Together, they give you a good understanding of when super
can be used correctly and how to avoid the problem you see here. 在一起,它们使您对何时可以正确使用
super
以及如何避免在此处看到的问题有一个很好的了解。
(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? 您究竟如何实例化Top对象?
Given your code above, the following works fine: 鉴于上面的代码,以下代码可以正常工作:
topObj = Top()
middleObj = Middle("middle")
baseObj = Base("base", "type")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.