在不通过self的情况下声明Subclass

时间:2018-05-20 17:14:38

标签: python python-3.x

我有一个抽象基类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):的调用会有效。

问题:

  1. 我在实施__str__(self):

    时才发现此错误

    在Python 3.x中从没有参数的子进程调用父构造函数时,是否需要传递self

  2. 假设MountainBike现在设置cadencegearspeed这意味着在我的子类中构造函数将如下所示:

    class MountainBike(Bicycle):
    
        def __init__(self, cadence, gear, speed):
            super().__init__(cadence,gear,speed)
    
  3. 注意,self没有传递super,因为据我所知,它可以抛弃变量赋值。这个假设是否正确?

1 个答案:

答案 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方法。

另见:https://docs.python.org/3/library/functions.html#super