Python __init__: An Overview – Great Learning

python __init__

  1. What is __init__ in Python?
  2. How Does __init__() Method Work?
  3. Python __init__: Syntax and Examples
  4. Types of __init__ Constructor
  5. Use of Python __init__
  6. Conclusion

What is __init__ in Python?

A constructor of a class in Python is defined using the __init__ method. The python __init__ is a reserved method in Python that behaves like any other member function of the class, except the statements written under its definition are used to initialize the data members of a class in Python, i.e. it basically contains assignment statements. This method is automatically called at the time of class instantiation or object creation. 

In case of inheritance, the sub class inherits the __init__ method of the base class along with the other accessible class members. Hence, the object of the base class automatically calls the python __init__ constructor of the base class at the time of its creation since it is called by the sub class __init__ constructor. 

How Does __init__() Method Work?

The python __init__ method is declared within a class and is used to initialize the attributes of an object as soon as the object is formed. While giving the definition for an __init__(self) method, a default parameter, named ‘self’ is always passed in its argument. This self represents the object of the class itself. Like in any other method of a class, in case of __init__ also ‘self’ is used as a dummy object variable for assigning values to the data members of an object. 

The __init__ method is often referred to as double underscores init or dunder init for it has two underscores on each side of its name. These double underscores on both the sides of init imply that the method is invoked and used internally in Python, without being required to be called explicitly by the object. 

This python __init__ method may or may not take arguments for object initialisation. You can also pass default arguments in its parameter. However, even though there is no such concept of Constructor Overloading in Python, one can still achieve polymorphism in the case of constructors in Python on the basis of its argument.

Also Read: Set in Python – How to Create a Set in Python?

Init in Python: Syntax and Examples

We can declare a __init__ method inside a class in Python using the following syntax:

class class_name():
          
          def __init__(self):
                  # Required initialisation for data members

          # Class methods
                 …
                 …

Let’s take an example of a class named Teacher in Python and understand the working of __init__() method through it better. 

class Teacher:
    # definition for init method or constructor
    def __init__(self, name, subject):
        self.name = name
        self.subject = subject
     # Random member function
    def show(self):
        print(self.name, " teaches ", self.subject)
 T = Teacher('Preeti Srivastava', "Computer Science")   # init is invoked here
T.show()

Output:

Now, for the scenarios where you are required to achieve polymorphism through __init__() method, you can go with the following syntax.

class class_name():
          
          def __init__(self, *args):
                   Condition 1 for *args:
                         # Required initialisation for data members
                  Condition 2 for *args:
                        # Required initialisation for data members
                
                    ………
                    ………

          # Class methods
                 …
                 …

In this case, the type of argument passed in place of *args decide what kind of initialisation has to be followed. Take a look at the example given below to get some more clarity on this. 

class Teacher:
     def __init__(self, *args): 

         # Naming the teacher when a single string is passed
         if len(args)==1 & isinstance(args[0], str):
             self.name = args[0]
         
         # Naming the teacher as well as the subject    
         elif len(args)==2:
             self.name = args[0]
             self.sub = args[1]
          
         # Storing the strength of the class in case of a single int argument
         elif isinstance(args[0], int):
             self.strength = args[0]
             
t1 = Teacher("Preeti Srivastava")
print('Name of the teacher is ', t1.name)
 
t2 = Teacher("Preeti Srivastava", "Computer Science")
print(t2.name, ' teaches ', t2.sub)
 
t3 = Teacher(32)
print("Strength of the class is ", t3.strength)

Output:

Types of __init__ Constructor

There are mainly three types of Python __init__ constructors:

  1. Default __init__ constructor
  2. Parameterised __init__ Constructor
  3. __init__ With Default Parameters

1. The Default __init__ Constructor

The default __init__ constructor in Python is the constructor that does not accept any parameters, except for the ‘self’ parameter. The ‘self’ is a reference object for that class. The syntax for defining a default __init__ constructor is as follows:

class class_name():
          
          def __init__(self):
                  # Constructor statements

          # other class methods
                 …
                 …

The syntax for creating an object for a class with a default __init__ constructor is as follows:

Object_name = class_name()

Example:

class Default():
    
    #defining default constructor
    def __init__(self):
        self.var1 = 56
        self.var2 = 27
        
    #class function for addition
    def add(self):
        print("Sum is ", self.var1 + self.var2)

obj = Default()     # since default constructor doesn’t take any argument
obj.add()

Output:

2. Parameterised __init__ Constructor

When we want to pass arguments in the constructor of a class, we make use of the parameterised __init__ method. It accepts one or more than one argument other than the self. The syntax followed while defining a parameterised __init__ constructor has been given below:

class class_name():
          
          def __init__(self, arg1, arg2, arg3, …):
                  self.data_member1 = arg1
                  self.data_member2 = arg2
                  self.data_member2 = arg2
                  ……
                  ……

          # other class methods
                 …
                 …

We declare an instance for a class with a parameterised constructor using the following syntax:

Object_name = class_name(arg1, arg2, arg3,…)

Example:

class Default():
    
    #defining parameterised constructor
    def __init__(self, n1, n2):
        self.var1 = n1
        self.var2 = n2
        
    #class function for addition
    def add(self):
        print("Sum is ", self.var1 + self.var2)

obj = Default(121, 136)              #Creating object for a class with parameterised init
obj.add()

Output:

3. The __init__ method with default parameters

As you might already know, we can pass default arguments to a member function or a constructor, be it any popular programming language. In the very same way, Python also allows us to define a __init__ method with default parameters inside a class. We use the following syntax to pass a default argument in an __init__ method within a class.

class ClassName:
         def __init__(self, *list of default arguments*):
             # Required Initialisations
    
        # Other member functions
                ……
               …….

Now, go through the following example to understand how the __init__ method with default parameters works.

class Teacher:
    # definition for init method or constructor with default argument
    def __init__(self, name = "Preeti Srivastava"):
        self.name = name
     # Random member function
    def show(self):
        print(self.name, " is the name of the teacher.")
        
t1 = Teacher()                             #name is initialised with the default value of the argument
t2 = Teacher('Chhavi Pathak')    #name is initialised with the passed value of the argument
t1.show()
t2.show()

Output:

Use of Python __init__

As discussed earlier in this blog and seen from the previous examples, __init__ method is used for initialising the attributes of an object for a class. We have also understood how constructor overloading can be achieved using this method. Now, let us see how this __init__ method behaves in case of inheritance. 

Inheritance allows the child class to inherit the __init__() method of the parent class along with the other data members and member functions of that class.  The __init__ method of the parent or the base class is called within the __init__ method of the child or sub class. In case the parent class demands an argument, the parameter value must be passed in the __init__ method of the child class as well as at the time of object creation for the child class. 

class Person(object):
    def __init__(self, name):
        self.name = name
        print("Initialising the name attribute")

class Teacher(Person):
    def __init__(self, name, age):
        Person.__init__(self, name)   # Calling init of base class
        self.age = age
        print("Age attribute of base class is initialised")
        
    def show(self):
        print("Name of the teacher is ", self.name)
        print("Age of the teacher is ", self.age)
        
t = Teacher("Allen Park", 45)   # The init of subclass is called
t.show()

Output:

From the above output, we can trace the order in which the __init__ constructors have been called and executed. The object ‘t’ calls the constructor of the Teacher class, which transfers the control of the program to the constructor of the Person class. Once the __init__ of Person finishes its execution, the control returns to the constructor of the Teacher class and finishes its execution. 

Conclusion

So, to sum it all up, __init__ is a reserved method for classes in Python that basically behaves as the constructors. In other words, this method in a Python class is used for initialising the attributes of an object. It is invoked automatically at the time of instance creation for a class. This __init__ constructor is invoked as many times as the instances are created for a class. We can use any of the three types of __init__ constructors – default, parameterised, __init__ with default parameter – as per the need of our programming module. The ‘self’ is a mandatory parameter for any member function of a class, including the __init__ method, as it is a reference to the instance of the class created. 

Even though Python does not support constructor overloading, the concept of constructor overloading can be implemented using the *args that are used for passing different numbers of arguments for different objects of a class. Furthermore, we can use the if-else statements for initialising the attributes according to the different types of arguments within the __init__ constructor.  To know more about Classes and Objects in Python, you can check out this blog.

We have also seen how the __init__ method of a class works with inheritance. We can easily call the __init__ method of the base class within the __init__ method of the sub class. When an object for the subclass is created, the __init__ method of the sub class is invoked, which further invokes the __init__ method of the base class.

Leave a Reply

Your email address will not be published.