多重继承和调用 super()
Multiple Inheritance and calling super()
我收到错误:
TypeError: __init__() 正好接受 2 个参数(给定 3 个)
尝试从 class 顶部实例化对象时:
super(Middle1, self).__init__(姓名, "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()
我对这个多重继承问题有什么不理解的?
注:这是python2.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()
您具体是如何实例化 Top 对象的?
鉴于您上面的代码,以下工作正常:
topObj = Top()
middleObj = Middle("middle")
baseObj = Base("base", "type")
首先得看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
的每次调用代表哪个 class。
您的错误是认为对 super(Middle1, self)
的调用指的是 Middle1
的(唯一)基数 class Base
。它不是:它指的是 self.__class__
的 MRO 中 Middle1
之后的 class。因为 self.__class__
是 Top
,下一个 class 是 Middle2
,它的 __init__
只接受一个参数。
要从方法中正确使用 super
,您需要确保该方法在 every class 中采用相同的参数,因为您无法预测class 的方法将通过查看代码本身来调用;它完全取决于启动调用链的对象的类型,它可能是 class 你甚至还没有意识到的。
有两个post我建议阅读:
结合使用它们,您可以很好地了解何时可以正确使用 super
以及如何避免您在此处看到的问题。
(坦白说,我最近都没读过 post,所以我不会尝试总结每本书中提出的建议。)
我收到错误: TypeError: __init__() 正好接受 2 个参数(给定 3 个)
尝试从 class 顶部实例化对象时:
super(Middle1, self).__init__(姓名, "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()
我对这个多重继承问题有什么不理解的?
注:这是python2.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()
您具体是如何实例化 Top 对象的?
鉴于您上面的代码,以下工作正常:
topObj = Top()
middleObj = Middle("middle")
baseObj = Base("base", "type")
首先得看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
的每次调用代表哪个 class。
您的错误是认为对 super(Middle1, self)
的调用指的是 Middle1
的(唯一)基数 class Base
。它不是:它指的是 self.__class__
的 MRO 中 Middle1
之后的 class。因为 self.__class__
是 Top
,下一个 class 是 Middle2
,它的 __init__
只接受一个参数。
要从方法中正确使用 super
,您需要确保该方法在 every class 中采用相同的参数,因为您无法预测class 的方法将通过查看代码本身来调用;它完全取决于启动调用链的对象的类型,它可能是 class 你甚至还没有意识到的。
有两个post我建议阅读:
结合使用它们,您可以很好地了解何时可以正确使用 super
以及如何避免您在此处看到的问题。
(坦白说,我最近都没读过 post,所以我不会尝试总结每本书中提出的建议。)