Geekflare is supported by our audience. We may earn affiliate commissions from buying links on this site.
In Development Last updated: June 20, 2023
Share on:
Invicti Web Application Security Scanner – the only solution that delivers automatic verification of vulnerabilities with Proof-Based Scanning™.

Looking to get started with object-oriented design in Python? Take the first steps today by learning about Python’s __init__ method.

In this tutorial, we’ll go over the basics of Python classes and objects, then proceed to learn about the __init__ method.

By the end of this tutorial, you will be able to answer the following questions:

  • What are instance variables or instance attributes?
  • How does the init method help in initializing the instance attributes?
  • How can we set default values for attributes?
  • How can we use class methods as constructors to create objects?

Let’s get started.

Python Classes and Objects

Classes are fundamental to object-oriented programming in Python. We can create a class and define attributes and methods—to bind together data and associated functionality.

Once we’ve created a class, we can use it as a blueprint (or a template) to create objects (instances).

👩‍🏫Example time! Let’s create an Employee class where every object of this class has the following attributes:

  • full_name: the full name of the employee in the firstName lastName format
  • emp_id: the employee id
  • department: the department they belong to
  • experience: the number of years of experience they have
Python-Classes-and-Objects

What does this mean? 🤔

Each individual employee will be an instance or object of the Employee class. And each object will have its own value for the full_name, emp_id, department, and experience.

These attributes are also called instance variables, and we’ll use the terms attributes and instance variables interchangeably.

Python-Objects

We’ll get to adding attributes in a bit. For now we create an Employee class like so:

class Employee:
    pass

Using pass (as a placeholder) helps us avoid errors when we run the script.

Though the current version of the Employee class is not very helpful, it’s still a valid class. So we can create objects of the Employee class:

employee_1 = Employee()

print(employee_1)
#Output: <__main__.Employee object at 0x00FEE7F0>

We can as well add attributes and initialize them with values as shown:

employee_1.full_name = 'Amy Bell'
employee_1.department = 'HR'

But this approach to adding instance attributes is both inefficient and prone to errors. Also, this does not allow the use of class as a template to create objects. Here’s where the __init__ method helps.

Understanding the Role of __init__ Method in a Python Class

Method-in-a-Python-Class

We should be able to initialize the instance variables when instantiating an object and the __init__ method helps us do that. The __init__ method is called every time a new object of the class is created to initialize the values of the instance variables.

If you’ve programmed in a language like C++, you’ll see that the __init__  method works similarly to constructors.

Defining the __init__ Method

Let’s add the __init__ method to the Employee class:

class Employee:
    def __init__(self, full_name,emp_id,department,experience):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience

The self parameter refers to the instance of the class, and the self.attribute initializes the instance attribute to the value on the right-hand side.

We can now create objects like so:

employee_2 = Employee('Bella Joy','M007','Marketing',3)
print(employee_2)
# Output: <__main__.Employee object at 0x017F88B0>

When we print out the employee objects, we don’t get any useful information except for the class that they belong to. Let’s add a __repr__ method that defines a representation string for the class:

 def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

Adding the __repr__ to the Employee class, we have:

class Employee:
    def __init__(self, full_name,emp_id,department,experience):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience
    
     def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

Now the employee objects have a helpful representation string:

print(employee_2)
# Output: Bella Joy,M007 from Marketing with 3 years of experience.

Some Conventions

Before we proceed further, here are a couple of notes:

  • We used self as the first parameter in the __init__ method to refer to the class instance itself and used self.attribute_name to initialize the various attributes. Using self is the preferred convention (you can use any other name though).
  • When defining the __init__ method, we set the parameter names in the __init__ definitions to match the names of the attributes. This improves readability.

How to Add Default Values for Attributes

How-to-Add-Default-Values-for-Attributes

In the example we have coded so far, all the attributes are required. Meaning object creation is successful only if we pass in the values for all the fields to the constructor.

Try to instantiate an object of the Employee class without passing in the value for the experience attribute:

employee_3 = Employee('Jake Lee','E001','Engineering')

You’ll get the following error:

Traceback (most recent call last):
  File "main.py", line 22, in <module>
    employee_3 = Employee('Jake Lee','E001','Engineering')
TypeError: __init__() missing 1 required positional argument: 'experience'

But if you want to make certain attributes optional, you can do so by providing default values for for those attributes when defining the __init__ method.

Here we provide a default value of 0 for the experience attribute:

class Employee:
    def __init__(self, full_name,emp_id,department,experience=0):
        self.full_name = full_name
        self.emp_id = emp_id
        self.department = department
        self.experience = experience
    
     def __repr__(self):
        return f"{self.full_name},{self.emp_id} from {self.department} with {self.experience} years of experience."

The employee_3 object is created without value for the experience attribute; the default value of 0 is used for experience.

employee_3 = Employee('Jake Lee','E001','Engineering')
print(employee_3.experience)
# Output: 0

Alternative Class Constructors Using Class Methods

Alternative-Class-Constructors-Using-Class-Methods

So far we’ve only seen how to define the __init__ method and set default values for attributes when needed. We also know that we need to pass in the values for the required attributes in the constructor.

Sometimes, however, the values for these instance variables (or attributes) may be available in a different data structure, such as a tuple, a dictionary or a JSON string.

So what do we do?

Let’s take an example. Suppose we have values of the instance variable in a Python dictionary:

dict_fanny = {'name':'Fanny Walker','id':'H203','dept':'HR','exp':2}

We can tap into the dictionary and get all the attributes like so:

name = dict_fanny['name']
id = dict_fanny['id']
dept = dict_fanny['dept']
exp = dict_fanny['exp']

After this you can create an object by passing in these values to the class constructor:

employee_4 = Employee(name, id, dept, exp)
print(employee_4)
# Output: Fanny Walker,H203 from HR with 2 years of experience.

Remember: you need to do this for every new object that you create. This approach is inefficient and we can definitely do better. But how?

In Python, we can use class methods as constructors to create objects of the class. To create a class method we use the @classmethod decorator.

Let’s define a method that parses the dictionary, gets the instance variable values, and uses them to construct Employee objects.

    @classmethod
    def from_dict(cls,data_dict):
        full_name = data_dict['name']
        emp_id = data_dict['id']
        department = data_dict['dept']
        experience = data_dict['exp']
        return cls(full_name, emp_id, department, experience)

When we need to create objects using data from the dictionary, we can use the from_dict() class method.

💡 Notice the use of cls in the class method instead of self. Just the way we use self to refer to the instance, cls is used to refer to the class. Also, class methods are bound to the class and not objects.

So when we call the class method from_dict() to create objects, we call it on the Employee class:

emp_dict = {'name':'Tia Bell','id':'S270','dept':'Sales','exp':3}
employee_5 = Employee.from_dict(emp_dict)
print(employee_5)
# Output: Tia Bell,S270 from Sales with 3 years of experience.

Now if we have a dictionary for each of the n employees, we can use the from_dict() class method as a constructor to instantiate in objects—without having to retrieve the instant variable values from the dictionary.

📝A Note on Class Variables

Here we defined the class method that is bound to the class and not individual instances. Similar to class methods, we can also have class variables.

Like class methods, class variables are bound to the class and not an instance. When an attribute takes a fixed value for all instances of the class, we can consider defining them as class variables.

FAQs

1. Why do you need the __init__ method in Python?

The __init__ method in a class definition allows us to initialize the attributes or instance variables of all instances of the class. The __init__  method is called every time a new instance of the class is created.

2. Can you have multiple __init__ methods in a Python class?

The goal of having multiple __init__ methods in a Python class is to provide multiple constructors that instantiate objects. But you cannot define multiple  __init__ methods. If you define multiple  __init__ methods, the second and the most recent implementation will overwrite the first. However you can use the @classmethod decorator to define class methods that can be used as constructors to instantiate objects.

3. What happens if you don’t define the __init__ method in a class?

If you don’t define the __init__ method, you can still instantiate objects. However, you will have to manually add instance variables and assign values to each of them. You will not be able to pass in the values for the instance variables in the constructor. This is not only prone to errors but also defeats the purpose of having the class as a blueprint from which we can instantiate objects.

4. Can you have default values for arguments in the __init__ method?

Yes, it is possible to provide default values for one or more attributes when defining the __init__ method. Providing default values helps make those attributes optional in the constructor. The attributes take the default values when we do not pass in the values for these attributes in the constructor.

5. Can you modify attributes outside of the __init__ method?

Yes, you can always update the value of an attribute outside the __init__ method. You can also add new attributes dynamically to an instance after you’ve created the particular instance.

Conclusion

In this tutorial, we learned how to use the __init__ method to initialize the values of instance variables. Though this is straightforward, it can be repetitive—especially when you have a lot of attributes. 

If you’re interested, you can explore the dataclasses module. In Python 3.7 and later, you can use the built-in data classes module to create data classes that store data. In addition to default implementations of the  __init__ and other commonly used methods; they come with a lot of cool features for type hints, complex default values, and optimization.

Next, learn more about if __name__==’__main__’ in Python.

  • Bala Priya C
    Author
    Bala Priya is a developer and technical writer from India with over three years of experience in the technical content writing space. She shares her learning with the developer community by authoring tech tutorials, how-to guides, and more…. read more
  • Narendra Mohan Mittal
    Editor

    Narendra Mohan Mittal is a Senior Digital Branding Strategist and Content Editor with over 12 years of versatile experience. He holds an M-Tech (Gold Medalist) and B-Tech (Gold Medalist) in Computer Science & Engineering.


    read more
Thanks to our Sponsors
More great readings on Development
Power Your Business
Some of the tools and services to help your business grow.
  • Invicti uses the Proof-Based Scanning™ to automatically verify the identified vulnerabilities and generate actionable results within just hours.
    Try Invicti
  • Web scraping, residential proxy, proxy manager, web unlocker, search engine crawler, and all you need to collect web data.
    Try Brightdata
  • Monday.com is an all-in-one work OS to help you manage projects, tasks, work, sales, CRM, operations, workflows, and more.
    Try Monday
  • Intruder is an online vulnerability scanner that finds cyber security weaknesses in your infrastructure, to avoid costly data breaches.
    Try Intruder