我有一个抽象基类Bicycle
:
from abc import ABC, abstractmethod
class Bicycle(ABC):
def __init__(self, cadence = 10, gear = 10, speed = 10):
self._cadence = cadence
self._gear = gear
self._speed = speed
@abstractmethod
def ride(self):
pass
def __str__(self):
return "Cadence: {0} Gear: {1} Speed: {2}".format(self._cadence,
self._gear, self._speed)
和子类MountainBike
:
from Bicycle import Bicycle
class MountainBike(Bicycle):
def __init__(self):
super().__init__(self)
def ride(self):
return "Riding my Bike"
以下代码会产生recursion error,但如果我从self
移除super().__init__(self)
,则对__str__(self):
的调用会有效。
问题:
我在实施__str__(self):
在Python 3.x中从没有参数的子进程调用父构造函数时,是否需要传递self
?
假设MountainBike
现在设置cadence
,gear
,speed
这意味着在我的子类中构造函数将如下所示:
class MountainBike(Bicycle):
def __init__(self, cadence, gear, speed):
super().__init__(cadence,gear,speed)
注意,self
没有传递super
,因为据我所知,它可以抛弃变量赋值。这个假设是否正确?
答案 0 :(得分:3)
self
隐式传递给超级调用,因此添加它会显式发送两次:
def __init__(self):
super().__init__(self)
最终会调用Bicycle(self, self)
,这与Bicycle(self, cadence=self)
相同。
稍后,您可能已尝试将您的实例转换为str
(例如将其打印出来),因此称之为:
def __str__(self):
return "Cadence: {0} Gear: {1} Speed: {2}".format(self._cadence,
self._gear, self._speed)
该代码试图将self._cadence
转换为字符串而self._cadence
由于先前的错误而导致self
,因此它会继续无限递归(直到递归异常)。
请注意super()
有两种形式:带参数和不带参数,因此有两种正确的方法来修复代码。
Python 3方式(不带参数):
def __init__(self):
super().__init__()
旧的Python 2方式,更明确:
def __init__(self):
super(MountainBike, self).__init__()
两者都是相同的,即它们为您提供已经具有隐式__init__
的绑定self
方法。