0

I am new to classes in python. I searched and went through so many articles on super() method which creates so much of confusion.

Type - 1

class Square():
    def __init__(self,side):
        self.side = side
        print("Its confusing")
        super().__init__()
  
    def area(self):
        return self.side * self.side
    
c = Square()
print(c.area())

In Type - 1 , if I mention super().__init__() what is the use of it? I don't understand why we use super().__init__() in a newly created class which is not inherited from any other class. And I don't understand what it does here.

If we give it after assigning self.side = side it runs properly and is executed.

Type - 2

class Square():
    def __init__(self):
        # self.side = side
        # print("Its confusing")
        super().__init__()
e = Square()
e()

If I just give only super().__init__() inside __init__ it gives error. TypeError: 'Square' object is not callable

My doubt is:

1.Can we use super().__init__() in a newly created class? and It runs well without error.

2.Then why is Type - 2 throwing error if I put only super().__init__() inside __init__?

Can you please make it in simple words?

martineau
  • 119,623
  • 25
  • 170
  • 301
shaila
  • 177
  • 2
  • 10
  • inherits from `object` – cards Sep 26 '21 at 09:37
  • in your text with ` super().init() ` you mean super().__init__()? – cards Sep 26 '21 at 09:40
  • "every" class is a subclass of `object`, try to print `issubclass(Square, object)`. Usually it is redundant and omit it – cards Sep 26 '21 at 09:47
  • Your `type-2` code is just a typo. You have `e()`. Why would you deliberately cause an error when your class isn't callable? – quamrana Sep 26 '21 at 09:49
  • 1
    You should look at the [answers](https://stackoverflow.com/questions/3277367/how-does-pythons-super-work-with-multiple-inheritance) to this question. `super().__init__()` is really useful in multiple inheritance. – quamrana Sep 26 '21 at 09:52
  • When there's no base class, there's usually little reason to use `super()` except in a rare cases where you want to use the method of the default base class `object` to avoid the method in the current class. For example the class with its own `__getattr__` might want to call the "normal" method in some situations to avoid calling the overridden one. – martineau Sep 26 '21 at 09:56

2 Answers2

3

For type-1 because Square class does not inherit from any base class, then the call for super().__init__() actually does nothing.

However, it's still good to keep this code, in case you use Square class for multiple inheritance. There is an example in a different question, see here: https://stackoverflow.com/a/8613067/362792. So copying that example, suppose you had class Square, class Color, and then class ColoredSquare:

class ColoredSquare(Square, Color):
   ...

In this case, when creating ColoredSquare instance, the super().__init__() from Square is actually calling Color.__init__() method. So it's indeed necessary then.


For type-2, your error is not from the init method. Instead, it's actually e() is producing your error for "TypeError: 'Square' object is not callable".

To use an object in this way you need to have call method. eg.

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

    def __call__(self):
        print('call for square')


e = Square()
e()
Hitobat
  • 2,847
  • 1
  • 16
  • 12
0

Inheritance is used to recycle code... and you use super to "fetch" code defined in a parent class.

# parent class
class Parallelogram:
    def __init__(self, side1, side2):
        self.side1, self.side2 = side1, side2

    def area(self):
        return self.side1 * self.side2


# child class
class Square(Parallelogram):
    def __init__(self, side):
        super().__init__(side, side)


p = Parallelogram(2, 3)
print(p.area())
# 6

s = Square(4)
print(s.area())
# 16

print(issubclass(Parallelogram, object))
#True
print(issubclass(Square, Parallelogram))
#True

print(hasattr(Square, 'area')) # inherited from the parent 
True
cards
  • 3,936
  • 1
  • 7
  • 25
  • btw its unfortunate that you show the `Square` class forwarding its `area()` method to its base class. In this case that `area()` method is redundant and can be omitted. This could be misinterpreted as the correct way to implement methods in derived classes. – quamrana Sep 26 '21 at 10:02
  • @quamrana was it also in python2.7? – cards Sep 26 '21 at 10:06
  • What is the `it` you refer to? Certainly `super()` worked differently in python 2. – quamrana Sep 26 '21 at 10:08
  • sorry, I meant if also in python2.7 declaring area from Square like that would be redundant – cards Sep 26 '21 at 10:09
  • Yes, python 2/3 did not change in that respect. Its the same in most OOP languages. The whole point of inheritance is to be able to inherit all of the parent's methods without the programmer having to do any more coding for the derived class. – quamrana Sep 26 '21 at 10:11
  • Maybe old memories from Java? I will edit it then. Thanks for your remarks! – cards Sep 26 '21 at 10:12