问题描述
我一直在研究Python 3(我的代码示例使用3.7.2)以及如何在类继承多个类时正确使用 super()
。
I've been doing research on Python 3 (my code sample uses 3.7.2) and how to properly use super()
when a class inherits more than one class.
我已阅读此,以及此和此。我认为问题在于SO链接适用于旧版本的Python,而本文则适用于Python 3,但仍然令人困惑。
I've read this page, and this page and this article. I think the problem is that the SO links are for an older version of Python, while the article is for Python 3, but it's still confusing.
假设我有以下代码(不要担心,如果您认为可以对关系进行更好的建模,这只是一个示例来说明我的问题):
Suppose I had the following code (don't worry if you think that the relationship can be modeled better, this is just an example to illustrate my problem):
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 __(名称,损坏)
和 super().__ init __(自身,金额)
,正确的方法初始化父级构造函数?
The code works and called the desired parent classes, but I want to make sure, when using Python 3.7, and super()
, is doing super().__init__(name, damage)
and super().__init__(self, amount)
, the correct way to initialize the parent constructors?
本文没有这样做,而是将 super()
称为仅一个类( RightPyramid(Square,Triangle)
)。
The article doesn't do that, instead it called the super()
for only one class (RightPyramid(Square, Triangle)
).
我只想确保自己在正确的路线,并采取适当的做法。
I just want to make sure I'm on the right track, and using proper practices.
推荐答案
super()
需要您的代码合作。您的武器
和 Reloadable
类没有,因此您实际上不想使用 super()
在这里。您可以直接在这些基类上调用未绑定方法:
super()
requires your code cooperates. Your Weapon
and Reloadable
classes don't, so you actually don't want to use super()
here. You'd call the unbound methods directly on those base 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
。
Without super()
, the __init__
methods are unbound so you need to pass in self
explicitly.
参见由Python核心开发人员Raymond Hettinger(或同名的Python会议演示有关如何以协作方式使用 super()
的很好概述。
See super() considered super! by Python core developer Raymond Hettinger (or the Python conference presentation of the same name for a great overview how to use super()
in a cooperative manner.
要完全协作, all 类ld传递类链中的 super()。< methodname>()
调用。对于 Reloadable
这样的混合类,您希望使用基本的无操作类或在调用 super()时处理错误。 ()
,或将参数作为关键字参数传递,并使每个 __ init __()
方法接受任意关键字参数再次传递:
To be fully cooperative, all classes in your hierarchy should pass on the super().<methodname>()
calls in the chain of classes. With mix-in classes like Reloadable
, you'd want to either use a base no-op class or handle errors when calling super().__init__()
, or pass on arguments as keyword arguments, and have each __init__()
method accept arbitrary keyword arguments to pass on again:
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")
这篇关于打电话给多个父母时难以理解super()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!