Search code examples
python-3.xsuper

I had to add a dummy parameter to BaseClass when using super().__init__() & don't know why


In the example code below I have added a 'dummy' parameter into BaseSensorClass to make it work. I don't understand why this is necessary.

I am writing some code to read sensor information for sensors of a few different type, so I created a BaseSensorClass with the common parameters and child classes for the sensor types. The example is simplified and just has a temperature sensor.

#!/usr/bin/python3

def main():
    s1 = TemperatureSensorClass(123,'first',  99.9)
    s2 = TemperatureSensorClass(234,'second', 22.2)
    print('s1 name = ',  s1.name,  ' id = ',  s1.id, ' temperature = ', s1.temperature)
    print('s2 name = ',  s2.name,  ' id = ',  s2.id, ' temperature = ', s2.temperature)

class BaseSensorClass:
    def __init__(self, dummy, id = 0, name = 'noname'):
        self.id = id
        self.name = name

class TemperatureSensorClass(BaseSensorClass):
    def __init__(self, id = 0, name = 'x', temperature = 0):
        super().__init__(self, id, name)
        self.temperature = temperature
        print('TemperatureSensorClass called with name=',  name)

if __name__ == "__main__":
    main()

I expected it to work without the 'dummy' parameter, but if I remove it I get an error TypeError: init() takes from 1 to 3 positional arguments but 4 were given


Solution

  • You shouldn't be passing self into __init__ manually. As with python instance methods, the reference to the object is automatically passed in. Doing super().__init__(a, b) more or less does <super class>.__init__(self, a, b). When you pass self in manually, you end up passing it into the constructor twice, which is why you're getting four positional arguments.

    The following code works and doesn't use dummy:

    def main():
        s1 = TemperatureSensorClass(123,'first',  99.9)
        s2 = TemperatureSensorClass(234,'second', 22.2)
        print('s1 name = ',  s1.name,  ' id = ',  s1.id, ' temperature = ', s1.temperature)
        print('s2 name = ',  s2.name,  ' id = ',  s2.id, ' temperature = ', s2.temperature)
    
    class BaseSensorClass:
        def __init__(self, id = 0, name = 'noname'):
            self.id = id
            self.name = name
    
    class TemperatureSensorClass(BaseSensorClass):
        def __init__(self, id = 0, name = 'x', temperature = 0):
            super().__init__(id, name)
            self.temperature = temperature
            print('TemperatureSensorClass called with name=',  name)
    
    if __name__ == "__main__":
        main()