我有一个抽象的基类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)
Run Code Online (Sandbox Code Playgroud)
和子类MountainBike:
from Bicycle import Bicycle
class MountainBike(Bicycle):
def __init__(self):
super().__init__(self)
def ride(self):
return "Riding my Bike"
Run Code Online (Sandbox Code Playgroud)
以下代码将导致递归错误,但如果我self从中删除super().__init__(self),则调用__str__(self):work.
题:
我实现的时候才发现这个错误 __str__(self):
在Python 3.x中从没有参数的子进程调用父构造函数时,是否self需要传递?
假设MountainBike现在设置cadence,gear,speed这意味着我的子类的构造看起来就像这样:
class MountainBike(Bicycle):
def __init__(self, cadence, gear, speed):
super().__init__(cadence,gear,speed)
Run Code Online (Sandbox Code Playgroud)注意,self没有被传递,super因为据我所知,它可以抛出变量赋值.这个假设是否正确?
self隐式传递给 super 调用,因此显式添加它会发送两次:
def __init__(self):
super().__init__(self)
Run Code Online (Sandbox Code Playgroud)
最终调用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)
Run Code Online (Sandbox Code Playgroud)
该代码尝试转换self._cadence为字符串,并且self._cadence由于self之前的错误,因此它继续无限递归(直到递归异常)。
请注意,super()有两种形式:带参数和不带参数,因此有两种正确的方法来修复代码。
Python 3 方式(不带参数):
def __init__(self):
super().__init__()
Run Code Online (Sandbox Code Playgroud)
旧的 Python 2 方式更明确:
def __init__(self):
super(MountainBike, self).__init__()
Run Code Online (Sandbox Code Playgroud)
两者的作用相同,即它们为您提供__init__已经具有隐式self.
另请参阅此处:https ://docs.python.org/3/library/functions.html#super