Python 3.x子类调用父类构造函数是否需传self的疑问
关于Python子类调用父类构造函数的疑问解答
先看你定义的抽象基类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"
这段代码会触发递归错误,但移除super().__init__(self)里的self后,__str__就能正常工作。接下来解答你的两个问题:
问题1:Python 3.x中子类调用无参父类构造函数时,是否需要传递self?
完全不需要!在Python 3里,super()会自动绑定当前类和实例的上下文,调用父类的方法时不需要手动传递self参数。你之前写的super().__init__(self)是错误的——父类的__init__方法第一个参数本来就是self,你额外传了一个self,相当于把父类__init__的cadence参数赋值成了当前实例对象。后续__str__尝试访问self._cadence时,它实际是个实例对象,格式化字符串的过程中会触发对这个对象的__str__调用,而这个对象又是当前实例,于是就陷入了无限递归,最终触发递归深度超出限制的错误。
正确写法是super().__init__(),super()会自动把当前实例作为self传递给父类的__init__方法,使用父类定义的默认参数初始化属性。
问题2:子类构造函数传递参数给父类时,不传递self的假设是否正确?
你的假设完全正确!当你要给父类构造函数传递自定义的cadence、gear、speed参数时,就像你写的这样:
class MountainBike(Bicycle): def __init__(self, cadence, gear, speed): super().__init__(cadence, gear, speed)
super()依然会自动处理self的传递,你只需要把父类__init__方法中除self之外的参数按顺序传进去就可以了。如果这时候额外加个self,反而会导致参数数量不匹配,或者像之前一样把错误的对象赋值给属性,引发问题。
内容的提问来源于stack exchange,提问作者user9814172
相关产品推荐
相关产品推荐

