Declaring Subclass without passing self

2024/9/8 10:37:38

I have an abstract base class Bicycle:

from abc import ABC, abstractmethodclass Bicycle(ABC):def __init__(self, cadence = 10, gear = 10, speed = 10):self._cadence = cadenceself._gear = gear         self._speed = speed@abstractmethoddef ride(self):passdef __str__(self):return  "Cadence: {0}  Gear: {1}  Speed: {2}".format(self._cadence, self._gear, self._speed)

and a subclass MountainBike:

from Bicycle import Bicycleclass MountainBike(Bicycle):def __init__(self):super().__init__(self)def ride(self):return "Riding my Bike"

The following code will cause a recursion error, but if I remove self from the super().__init__(self), the call to __str__(self): works.

Question:

  1. I only discovered this error when I implemented the __str__(self):

    In Python 3.x when calling the parent constructor from the child with no arguments, is passing self, necessary?

  2. Suppose MountainBike now sets the cadence, gear, speed this means in my subclass the constructor will look like this:

    class MountainBike(Bicycle):def __init__(self, cadence, gear, speed):super().__init__(cadence,gear,speed)
    

notice, self isn't being passed in the super because to my knowledge, it can throw the variable assignments off. Is this assumption correct?

Answer

self is passed implicitly to the super call, so adding it explicitly sends it twice:

def __init__(self):super().__init__(self)

That ends up calling Bicycle(self, self), which is the same as Bicycle(self, cadence=self).

Later on, you have probably tried convert your instance to str (e.g. to print it), so this was called:

def __str__(self):return  "Cadence: {0}  Gear: {1}  Speed: {2}".format(self._cadence, self._gear, self._speed)

That code tried to convert self._cadence to a string and self._cadence is self because of the previous error, so it continues in an endless recursion (until the recursion exception).


Note that super() takes two forms: with arguments and without arguments, so there are two correct ways to fix the code.

The Python 3 way (without arguments):

def __init__(self):super().__init__()

The old Python 2 way, which is more explicit:

def __init__(self):super(MountainBike, self).__init__()

Both do the same, i.e. they give you the bound __init__ method which already has the implicit self.

See also here: https://docs.python.org/3/library/functions.html#super

https://en.xdnf.cn/q/72843.html

Related Q&A

Flask-OIDC with keycloak - oidc_callback default callback not working

Im trying to use Flask-oidc in a simple flask application in order to add authentication via keycloak. However, once I log-in with valid credentials it goes back to /oidc_callback which doesnt exist. T…

Matplotlib: reorder subplots

Say that I have a figure fig which contains two subplots as in the example from the documentation:I can obtain the two axes (the left one being ax1 and the right one ax2) by just doing:ax1, ax2 = fig.a…

Filter values in a list using an array with boolean expressions

I have a list of tuples like this:listOfTuples = [(0, 1), (0, 2), (3, 1)]and an array that could look like this:myArray = np.array([-2, 9, 5])Furthermore, I have an array with Boolean expressions which…

Show two correlation coefficients on pairgrid plot with hue (categorical variable) - seaborn python

I found a function to compute a correlation coefficient and then add it to a pair plot (shown below). My issue is that when I run a pairplot with hue (a categorical variable) the correlation coefficien…

How to properly setup vscode with pyside? Missing suggestions

Im very new to pyside, qt and python. I managed to setup a project with a basic window and a push button which closes the app. My problem is, that somehow vscode wont show all properties available, eve…

Split marker and line in Legend - Matplotlib

I want to make a legend where I specify the value for the markers and the value for the lines but not the combination of both.This example should help to illustrate my goal:import matplotlib.pyplot as …

How do I loop over all items in a DynamoDB table using boto?

Id like to query a DynamoDB table and retrieve all the items and loop over them using boto. How do I structure a query or scan that returns everything in the table?

install pyopencv with pip on Mac OS X

I am trying to install pyopencv with pip in OS X Mountain Lion and it fails by import setuptools. Following is my work. what is "Library" in setuptools? I have not seen that before. I alread…

OpenCV remap interpolation error?

Im using opencv remap function to map an image to another coordinate system. However, my initial tests indicate that there are some issues with the interpolation. Here, I give a simple example of a co…

Installing python with python win32 extensions on a network drive

I need to keep a large number of Windows XP machines running the same version of python, with an assortment of modules, one of which is python-win32. I thought about installing python on a network dri…