我一直在研究Python 3(我的代码示例使用3.7.2)以及如何在类继承多个类时正确使用super()
。
我已经读过这个page,这个page和这个article。我认为问题在于SO链接适用于旧版本的Python,而本文则适用于Python 3,但仍然令人困惑。
假设我有以下代码(如果您认为可以更好地建模关系,请不要担心,这只是一个示例来说明我的问题):
class Weapon:
def __init__(self, name, damage):
self.name = name
self.damage = damage
class Reloadable:
def __init__(self, amount):
self.amount = amount
class Sniper(Weapon, Reloadable):
def __init__(self, name, damage, amount, scope_type):
super().__init__(name, damage)
super().__init__(self, amount)
self.scope_type = scope_type
def adjust_scope(self):
print("Adjusting my scope")
Main:
gun = Sniper("Standard Sniper", 10, 20, "small")
gun.adjust_scope()
print(Sniper.__mro__)
和MRO
:
(<class 'inheritnacewithsuper.Sniper'>,
<class 'inheritnacewithsuper.Weapon'>,
<class 'inheritnacewithsuper.Reloadable'>, <class 'object'>)
代码可以正常工作并调用所需的父类,但是我想确保在使用Python 3.7和super()
时,正在执行super().__init__(name, damage)
和super().__init__(self, amount)
的正确方法初始化父构造函数?
本文没有这样做,相反,它仅针对一个类(super()
)调用了RightPyramid(Square, Triangle)
。
我只想确保自己在正确的道路上并使用正确的做法。
答案 0 :(得分:2)
super()
需要您的代码合作。您的Weapon
和Reloadable
类不需要,因此您实际上不想在这里使用super()
。您可以直接在这些基类上调用未绑定方法:
class Sniper(Weapon, Reloadable):
def __init__(self, name, damage, amount, scope_type):
Weapon.__init__(self, name, damage)
Reloadable.__init__(self, amount)
self.scope_type = scope_type
在没有super()
的情况下,__init__
方法是不受约束的,因此您需要显式传递self
。
请参阅Python核心开发人员Raymond Hettinger的super() considered super!(或Python conference presentation of the same name),以概述如何协同使用super()
。
要完全合作,层次结构中的所有所有类应传递类链中的super().<methodname>()
调用。对于Reloadable
之类的混合类,您要么希望使用基本的无操作类,要么在调用super().__init__()
时处理错误,或者将参数作为关键字参数传递,并让每个{{1 }}方法接受任意关键字参数再次传递:
__init__()