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

6 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)
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.

题:

  1. 我实现的时候才发现这个错误 __str__(self):

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

  2. 假设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因为据我所知,它可以抛出变量赋值.这个假设是否正确?

zvo*_*one 3

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