打电话给多个父母时难以理解super()

时间:2019-02-14 16:14:43

标签: python inheritance constructor super

我一直在研究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)

我只想确保自己在正确的道路上并使用正确的做法。

1 个答案:

答案 0 :(得分:2)

super()需要您的代码合作。您的WeaponReloadable类不需要,因此您实际上不想在这里使用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__()