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 thefirstName lastName
formatemp_id
: the employee iddepartment
: the department they belong toexperience
: the number of years of experience they have

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.

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

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 usedself.attribute_name
to initialize the various attributes. Usingself
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

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

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 ofself
. 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
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.
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.
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.
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.
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 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 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