What Is init in Python? An Overview
For Developers

June 10, 2024

What Is init in Python? An Overview

Python object-oriented programming depends critically on the __init__ function. This unique function is triggered automatically when a class creates an object. This function lets us do any setup or configuration chores required and initialise the properties of an object. The importance of __init__ in Python, its syntax and usage, its function in inheritance, typical errors to avoid, and best practices for utilising it successfully will all be covered in this article. Given in this technology-driven world, the necessity of hiring proficient Python developers has become paramount for organizations. Companies can optimize the recruiting process by emphasizing critical competencies and implementing structured, well-defined interview questions. 

In addition to facilitating the development of Python code that is more resilient, the comprehension of these concepts also equips developers to address frequently asked interview questions. For example, interviewers frequently inquire about the __init__ method to evaluate a candidate's understanding of object-oriented programming in Python, as well as other fundamental functions such as enumerate, which simplifies loops by providing a counter to an iterable.

Fill your Python role with vetted senior tech talent from Index.dev global network. Simplify scaling today →

 

What is Object Oriented Programming?

Object-oriented programming, or OOP, is a way of writing code that involves creating things and talking to them. An object is a group of complex variables and functions that can stand in for real things, like a person, an airplane, or a button.

In Python, we use classes to define, start, and change objects. They are like models that are used to make things. To begin, let's make a Python class.

 

What is a Class?

A class is responsible for the definition and organisation of all objects that are generated from it. The class may be perceived as an object factory. For instance, consider the fox terrier, a dog breed. From an OOP perspective, it is possible to consider the classification of dogs as a class that encompasses the characteristics of a dog, such as its breed or eye colour. We can generate a dog object that will inherit the characteristics of its class, as a Fox Terrier is a dog. Methods and constructors are employed by classes to define and create objects.

 

User-Defined and Special Methods

Methods are functions that are intended to execute a particular task within a class. The language Python distinguishes between user-defined methods, which are written by the programmer, and special methods that are implemented within the language. A user-defined method is a function that is developed by the programmer to fulfil a particular purpose. For example, the dog object may have access to a walk() method in a dog class. This method is developed by the programmer, who then instructs it to execute specified tasks.

Double underscores are used to distinguish special methods, such as __init__. In order to optimise the functionality of classes, Python implements unique methods. The majority of them operate in the background and are invoked automatically by the program when necessary. It is impossible to designate them explicitly. For example, Python automatically invokes the __new__ method when a new object is created, which in turn invokes the __init__ method. When an object is printed using the print() method, the __str__ method is invoked. Conversely, user-defined methods, such as stefi.run(), are invoked explicitly.

 

The Constructor

Upon the formation of an object, the program invokes a unique method known as a constructor. The class employs the constructor to initialise the data members of the object. You can utilise a constructor to designate dog characteristics to each Fox Terrier object in our dog class example. The Python constructor is represented by the special method __init__.

Let us now examine the operation of the __init__ method in a Python program, armed with a comprehension of object-oriented programming and classes.

Read more: Unlocking Efficiency and Clarity in Python Development with Enumerate

 

What is __init__ in Python?

The __init__ method is equivalent to the default constructor in Java and C++. The object's state is initialised using constructors. 

When an object of the class is created, constructors are responsible for initialising (assigning values) the data members thereof.

A constructor, similar to methods, is composed of a sequence of statements (i.e., instructions) that are enacted during the creation of an object. It is executed immediately upon the instantiation of a class object.

The method is beneficial for performing any initialization that you wish to perform on your object.

# A Sample class with init method
class Person:

# init method or constructor
def __init__(self, name):
self.name = name

# Sample Method
def say_hi(self):
print('Hello, my name is', self.name)


p = Person('Nikhil')
p.say_hi()

OUTPUT:

Hello, My Name is Nikhil

Understanding the Code

A person named Nikhil is established in the preceding example. The argument "Nikhil" is passed to the __init__ method during the creation of a person. This argument is used to initialise the object.

The keyword "self" denotes the instance of a class and associates the attributes with the parameters provided. In the same way, numerous objects of the Person class can be generated by providing a variety of names as parameters.

The following is an example of __init__ in Python with parameters:

# A Sample class with init method
class Person:

# init method or constructor
def __init__(self, name):
self.name = name

# Sample Method
def say_hi(self):
print('Hello, my name is', self.name)


# Creating different objects
p1 = Person('Nikhil')
p2 = Person('Abhinav')
p3 = Person('Anshul')

p1.say_hi()
p2.say_hi()
p3.say_hi()

OUTPUT:

Hello, my name is Nikhil

Hello, my name is Abhinav

Hello, my name is Anshul

__init__ Method with Inheritance

Inheritance is the ability of a class to derive or inherit properties from another class. To illustrate the operation of __init__ in inheritance, we will look into the following example.

# Python program to
# demonstrate init with
# inheritance

class A(object):
def __init__(self, something):
print("A init called")
self.something = something


class B(A):
def __init__(self, something):
# Calling init of parent class
A.__init__(self, something)
print("B init called")
self.something = something


obj = B("Something")

OUTPUT:

A init called

B init called

The constructor of the parent class is invoked initially. However, in Python, it is not obligatory for the constructor of the parent class to always be invoked first.

The sequence in which the __init__ method is invoked for a parent or child class can be altered. This may be accomplished by invoking the constructor of the parent class immediately following the execution of the child class constructor. 

Example:

# Python program to
# demonstrate init with
# inheritance

class A(object):
def __init__(self, something):
print("A init called")
self.something = something


class B(A):
def __init__(self, something):
print("B init called")
self.something = something
# Calling init of parent class
A.__init__(self, something)


obj = B("Something")

OUTPUT:

B init called

A init called

 

How Does the __init__() Method Works?

The __init__ function in Python is defined within a class and serves the purpose of initialising the characteristics of an object immediately upon its creation. When defining a __init__(self) method, a default parameter called 'self' is always included in its argument. The term "self" refers to the instance of the class itself. In the __init__ method of a class, 'self' is used as a dummy object variable to assign values to the data members of an object, just as in any other method. 

The __init__ method is commonly known as "double underscores init" or "dunder init" because it is surrounded by two underscores on either side of its name. The presence of double underscores on both sides of the "init" function indicates that it is invoked and utilised internally in Python, without the need for explicit calling by the object. 

The __init__ function in Python may be used to initialise an object, and it has the option to accept parameters. Default arguments can be given in the parameters of the function. Although Python does not have the idea of Constructor Overloading, polymorphism may nonetheless be achieved in Python constructors based on their arguments.

 

Uses of Python __init__

The __init__ function is used to initialise the characteristics of an object for a class, as previously mentioned in this blog and demonstrated by the prior examples. We have also comprehended the process of achieving constructor overloading utilising this approach. Now, let us see the behaviour of this __init__ function in the context of inheritance. 

Inheritance enables the child class to acquire the __init__() method of the parent class, as well as the other data members and member functions of that class.  The __init__ method of the parent or base class is invoked within the __init__ method of the child or subclass. If the parent class requires an argument, the parameter value must be provided in both the __init__ method of the child class and when creating an object of 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()

By examining the output shown above, we can determine the sequence in which the __init__ constructors were invoked and performed. The object 't' invokes the constructor of the Teacher class, therefore transferring program control to the constructor of the Person class. After the __init__ method of the Person class completes its execution, the control is returned to the constructor of the Teacher class, which then concludes its execution. 

Read more: Java vs Python: Selecting the Right Programming Language (2024 Edition)

 

Using __init__ Method on Different Objects in Python

The __init__ method is unique to Python and is called immediately when an object is made. In this way, the method can be used to set up the object and give its properties values. Here are some different kinds of Python objects that can be used with the init method:

1. Simple class objects:

We have a simple example of making a class in Python. It's called "Person." This class has a unique method named "init" that is called when an object of the class is made. In this way, the method gets two options, "name" and "age," which can be used to change the Person object's "name" and "age" properties. In the end, we make a Person object with the name "Maria" and the age of 25. The console will show its properties. 

Look at this:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

Person1 = Person("Maria", 25)
print(Person1.name) # "Maria"
print(Person1.age) # 25

2. Objects of more complex classes:

The constructor (init) of the class is used to specify the attributes of the class, which in this instance are the make, model, year, and price of the vehicle. Next, we generate an object of the "Car" type and assign it the name "car1". The syntax "car1.attribute" can be used to display the attribute values of the object "car1" in the console, where the desired attribute name is presumed to be "attribute." 

Observe:

class Car:
    def __init__(self, brand, model, ano, preco):
        self.brand = brand
        self.model = model
        self.year = year
        self.price = price

car1 = Car("Ford", "Fiesta", 2015, 15000)
print(car1.brand) # "Ford"
print(car1.model) # "Fiesta"
print(car1.year) # 2015
print(car1.price) # 15000

3. List objects:

We now have an example that generates a list of three elements: "Sao Paulo," 25, and "Maria." It then employs a for loop to iterate over each element in the list and outputs each one. The variable elemento will be updated on each iteration of the for loop, matching each element in the list, as indicated by the syntax "for elemento in lista." Consequently, the print() function is employed to output each value of elemento in the iteration.

list1 = ["Maria", 25, "Sao Paulo"]

for element in list1:
    print(element)

# Output:
# Maria
# 25
# Sao Paulo

4. Dictionary objects:

This example generates a Python dictionary with three keys and their respective values: "name" with the value "Maria," "age" with the value 25, and "city" with the value "São Paulo." In this manner, a for loop is employed to iterate over the dictionary elements, which are the keys and values that are associated. The syntax indicates that the variable will be updated with the corresponding key value on each iteration, while also matching the dictionary key. Using the, the loop prints each key and value. This example will generate the following output: "name," "25," and "city."for chave, value in dictionary1.items() chavevalor print()

dictionary1 = {"name": "Maria", "age": 25, "city": "Sao Paulo"}

for key, value in dictionary1.items():
    print(key) # "nome"
    print(value) # 25

# Output:
# nome
# 25
# cidade

5. Custom class objects:

Finally, the following example establishes a "Animal" class that includes a constructor that specifies the animal's name and age.

Additionally, the class includes a "speak" method that displays the animal's name. Next, we generate the "Dog" class, which inherits the attributes and methods of the "Animal" class. The "Dog" class's constructor adds a new attribute, "raza," and invokes the "Animal" class's constructor. The "talk" method is being invoked on the "dog1" object, which was constructed as an instance of the "Dog" class. The animal's name, "Fido," is displayed by the "speak" method. The result of this example will be "The animal says: Fido."

Observe:

class Animal:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def speak(self):
        print("The animal says:")
        print(self.name)

class dog(Animal):
    def __init__(self, name, age, raza):
        super().__init__(name, age)
        self.raza = raza

dog1 = dog("Fido", 3, "Labrador")
dog.falar()
# Output:
# The animal says:
# Fido

 

__init__ Method for Inheritance in Python

In Python, inheritance—a technique for building classes that take on the characteristics and behaviors of other classes—is implemented using the function __init__. Using the keyword class followed by the names of the new class and the base class in quotes, one may create a new class that inherits from an existing class.

Using the method to initialize the properties of the new class, you can then specify its properties and methods inside the base class. Additionally, you may give new implementations of base class methods in the new class by using the term def.

Assume, for instance, that you wish to develop a car class that derives from another vehicle class. 

We can so proceed as follows:

class Car(Vehicle):
  def __init__(self, make, model, year):
    Vehicle.__init__(self, make, model, year)
    self.number_of_doors = 4
    self.color = "red"

  def start(self):
    print("Starting the engine...")

Here the class Car inherits from the class Vehicle and specifies a new property called number_of_doors and a new method called start() that supersedes the method of the class Vehicle.

We thus construct car objects that add additional behaviors and attributes exclusive to automobiles and inherit behaviors and attributes from the class Vehicle using the new class Car.

Struggling to find the right remote talent? Index.dev has you covered. We offer a global talent network of 15,000 vetted engineers, ready to join your team. Hire 7x faster →

 

More Examples of Using __init__ Method in Python

1. Simple class with single attribute:

class Person:
    def __init__(self, name):
        self.name = name

person1 = Person("Alice")
print(person1.name)                # Output: Alice

person2 = Person("Bob")
print(person2.name)                # Output: Bob

In this example, a basic class Person with a single attribute name is defined. With self.name = name, the __init__ function sets a parameter name to the object's name property. Following that, we construct two separate Person class instances, named person1 and person2. Each object is shown to have a distinct name property in the report.

2. Class with multiple attributes:

class Rectangle:
    def __init__(self, length, width):
        self.length = length
        self.width = width
        self.area = length * width

rectangle1 = Rectangle(4, 6)
print(rectangle1.length)  # Output: 4
print(rectangle1.width)   # Output: 6
print(rectangle1.area)    # Output: 24

rectangle2 = Rectangle(5, 10)
print(rectangle2.length)  # Output: 5
print(rectangle2.width)   # Output: 10
print(rectangle2.area)    # Output: 50

Here, we establish a class Rectangle with three properties: area, width, and length. Using the equation length * width, the __init__ method computes the area attribute given two inputs, length and width. We next construct rectangle1 and rectangle2, two different-length and -width instances of the Rectangle class. The result demonstrates that every item has distinct characteristics of length, breadth, and area.

3. Inheritance with super():

class Animal:
    def __init__(self, species):
        self.species = species

class Dog(Animal):
    def __init__(self, name, species):
        super().____init____(species)
        self.name = name

dog1 = Dog("Fido", "Canis lupus familiaris")
print(dog1.name)     # Output: Fido
print(dog1.species)  # Output: Canis lupus familiaris

dog2 = Dog("Rover", "Canis lupus familiaris")
print(dog2.name)     # Output: Rover
print(dog2.species)  # Output: Canis lupus familiaris

Here we create a subclass Dog that derives from Animal and a class Animal with a single property species. Two characteristics of the Dog class are its name and species. Two arguments are taken by the Dog class's __init__ method: name and species.

The __init__ method of the parent class Animal is called using the super() function to initialize the species attribute. This guarantees accurate setting of the species property prior to setting of the name attribute. We next make two Dog class instances, dog1 and dog2, with distinct names and species. The result reveals that every object has a distinct name and features of its species.

It is evident that the super() function in the Child class is used to access the constructor of the parent class here.

 

Best Practices for Using __init__ in Python

Here are some recommended practices that should be followed in order to make optimal use of the __init__ method:

  • It is imperative that the "self" argument be always included as the initial parameter in the specification of the __init__ method.
  • The __init__ method should be used to initialize all of the instance variables that are required.
  • It is best to avoid conducting laborious computations or actions that take a significant amount of time within the __init__ method. Instead, you should think about developing distinct procedures for such activities.
  • Maintain the __init__ method's concision and ensure that it is solely focused on initialization responsibilities.
  • In order to improve the readability of the code, you should give the instance variables names that are meaningful and descriptive.
  • Ensure that the __init__ and other class methods are named in accordance with consistent naming rules.

 

Conclusion

In summary, the __init__ method is a reserved method in Python that functions similarly to the constructors within classes. In other words, this method in a Python class is utilized to initialize the attributes of an object. It is executed automatically during the creation of a class instance. The __init__ constructor is called for each created instance of a class. Depending on the requirements of our programming module, we may employ any of the three varieties of __init__ constructors: default, parameterised, or __init__ with default parameter. '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 that was constructed. 

The concept of constructor overloading can be implemented by utilizing the *args, which are used to transmit varying numbers of arguments for various objects of a class, despite the fact that Python does not support them. In addition, the if-else statements can be employed to initialize the attributes in accordance with the various types of parameters presented in the __init__ constructor.  

Additionally, we have observed the interaction between inheritance and the __init__ method of a class. The __init__ method of the base class can be simply invoked within the __init__ method of the subclass. The __init__ method of the subclass is invoked upon the creation of an object for the subclass, which in turn invokes the __init__ method of the base class.

Read more: Best Practices for Using MongoDB with Django in Engineering and Hiring

Are you a skilled Python seeking a long-term remote opportunity? Join Index.dev to unlock high-paying remote careers with leading companies in the US, UK, and EU. Sign up today and take your career to the next level!

Struggling to find the right Java developer? We offer a global network of vetted Java developers, ready to join your team today in 48 hours. Hire faster, scale more easily!