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

2024-04-26 04:25:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在研究python3(我的代码示例使用3.7.2)以及如何在类继承多个类时正确使用super()。你知道吗

我读过这个page,这个page,这个article。我认为问题在于,SO链接是针对Python的旧版本的,而本文是针对python3的,但是仍然令人困惑。你知道吗

假设我有以下代码(如果您认为关系可以更好地建模,请不要担心,这只是一个示例来说明我的问题):

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'>)

代码可以工作并调用所需的父类,但是我想确保,在使用python3.7和super()时,是否使用了super().__init__(name, damage)super().__init__(self, amount)初始化父构造函数的正确方法?你知道吗

本文没有这样做,而是只为一个类调用了super()RightPyramid(Square, Triangle))。你知道吗

我只想确保我走上了正确的道路,并使用正确的做法。你知道吗


Tags: 代码nameselfinitdeftypeamountclass
1条回答
网友
1楼 · 发布于 2024-04-26 04:25:42

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这样的mix-in类,您可能希望在调用super().__init__()时使用base no op类或处理错误,或者将参数作为关键字参数传递,并让每个__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")

相关问题 更多 >