调用多个父项时无法理解 super()

Trouble understanding super() when calling multiple parents

我一直在研究 Python 3(我的代码示例使用 3.7.2)以及当 class 继承多个 class。

我读过这个 page, and this page and this 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'>)

代码有效并调用了所需的父 classes,但我想确保在使用 Python 3.7 和 super() 时正在执行 super().__init__(name, damage)super().__init__(self, amount),初始化父构造函数的正确方法?

这篇文章没有这样做,而是只为一个 class (RightPyramid(Square, Triangle)).

调用了 super()

我只是想确保我走在正确的轨道上,并使用正确的做法。

super() 需要您的代码 合作 。你的 WeaponReloadable class 没有,所以你实际上 不想在这里使用 super()。您将直接在这些基础 classes:

上调用未绑定方法
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

有关如何以合作方式使用 super() 的重要概述,请参阅 super() considered super! by Python core developer Raymond Hettinger (or the Python conference presentation of the same name

要充分合作,您层次结构中的 所有 classes 应该传递 classes 链中的 super().<methodname>() 调用.对于像 Reloadable 这样的混入 classes,您可能想要使用基本无操作 class 或在调用 super().__init__() 时处理错误,或者将参数传递为关键字参数,并让每个 __init__() 方法 接受 任意关键字参数以再次传递:

class Weapon:
    def __init__(self, name, damage, **kwargs):
        self.name = name
        self.damage = damage
        # pass on any remaining arguments
        super().__init__(**kwargs)

class Reloadable:    
    def __init__(self, amount, **kwargs):
        self.amount = amount
        # pass on any remaining arguments
        super().__init__(**kwargs)

class Sniper(Weapon, Reloadable):    
    def __init__(self, name, damage, amount, scope_type):
        self.scope_type = scope_type
        super().__init__(name=name, damage=damage, amount=amount)

    def adjust_scope(self):
        print("Adjusting my scope")