# Getting started with Python's `super()` function

As we all know, python can do both structural and object-oriented programming. As part of its OOP, it follows one key concept that is inheritance. 
To use the inheritance concept, python uses the `super()` function to refer to the parent class' methods. The `super()` function used in the child class creates a temporary object of the superclass, that allows the parent class to access the methods of the child class.

### Benefits of `super()` function:
1. We don't need to remember the name of the parent class. Calling the `super()` method will directly access the parent class without specifying the name of the parent class.
2. We can use it with single or multiple inheritances.
3. It is better for code reusability and modularity, which helps to keep the DRY(Do not Repeat Yourself)  approach.
4. The `super()` function is a dynamic function and goes along with the concept of the dynamically typed programming language of python.

### Limiting factors of `super()` function:
1. The arguments passed in the `super()` function and the arguments we have in the super function should match.
2. Every time we call the super method the keyword `super()` should be used.
3. We have to specify the exact class and methods present, which are referred to by the `super()` function.

### Using `super()` function in inheritance

Let us have a rectangle and a square function that is used to calculate the area and perimeter of the rectangle and the square. Normally what we do is the following:
```python
class Rectangle:
    def __init__(self, length, width):
        self.length = length
        self.width = width
    
    def area(self):
        return self.length*self.width

    def perimeter(self):
        return 2*self.length + 2*self.width


class Square:
    def __init__(self, length):
        self.length = length

    def area(self):
        return self.length**2

    def perimeter(self):
       return 4*self.length()
```
These are two simple classes Rectangle and Square. You can use these as:
```sh

>>> square = Square(7)
>>> square.area()
49
>>> rectangle = Rectangle(5,2)
>>> rectangle.perimeter()
14
```
A square is a special type of rectangle which have both of its sides equal to each other. So we can use inheritance in the Square class to reduce the code.
```python
class Rectangle:
    def __init__(self, length, width):
        self.length = length
        self.width = width

    def area(self):
        return self.length * self.width

    def perimeter(self):
        return 2 * self.length + 2 * self.width

#We'll declare that the Square class inherits from the Rectangle class
class Square(Rectangle):
    def __init__(self, length):
        super().__init__(length, length)
```
Here we've used the `super()`  function to call the `__init__()`  method of the Rectangle class, allowing us to use it in the Square class without repeating the same code twice. The core functionality remains the same after using the `super()` method:

```sh
>>> square = Square(5)
>>> square.area()
25
>>> square.perimeter()
20
```
Behind the scenes, when we call the `Square(5)` method, it goes on to the `__init__()` method and see the `super()` method which then calls the `__init__()` method of the Rectangle class and pass the length twice as arguments for length and width. After the Square is initialized, all other functions of the Rectangle can be used by it, allowing us to use them wherever we like.

### Conclusion
The `super()` method is a very useful method in python that is used while applying the inheritance of classes. It can be used with multiple inheritances as well. 









