The init() Method in Python
The init() Method
When you create an object, you usually want it to start with its own data: a user should have a username, a bank account should have an owner and a balance. Python provides a special method for exactly this purpose: __init__().
__init__() (pronounced "dunder init", short for "double underscore init") runs automatically every time a new object is created from a class.
What Does init() Do?
The main purposes of __init__() are to:
- Initialize object data — give each new object its starting values
- Assign values to object attributes — store the arguments passed when the object is created
- Perform setup tasks — such as validating input or preparing an empty list
__init__() is often called the class's constructor. Strictly speaking, Python creates the object first (using a method called __new__()) and then calls __init__() to initialize it — which is why it is more precisely called an initializer. For everyday programming, the two terms are used interchangeably.
How init() Works
When you create an object, Python:
- Creates a new, empty object.
- Calls
__init__()automatically, passing the new object asselfand your arguments as the remaining parameters. - Returns the initialized object.
Example: Initializing Object Attributes
class User:
def __init__(self, username, level):
self.username = username
self.level = level
u1 = User("alex", 5)
print(u1.username)
print(u1.level)
Expected output:
alex
5
Line by line:
| Code | What It Does |
|---|---|
def __init__(self, username, level): | Defines the initializer with two parameters after self |
self.username = username | Creates an attribute username on the object and stores the argument in it |
self.level = level | Creates an attribute level on the object |
User("alex", 5) | Creates an object; Python calls __init__(new_object, "alex", 5) |
Notice the difference between username and self.username:
usernameis a parameter — a temporary local variable that disappears when__init__()finishes.self.usernameis an attribute — it is stored on the object and lasts as long as the object exists.
Automatic Execution of init()
You never call __init__() yourself. Python runs it every time a new instance is created:
class Greeter:
def __init__(self):
print("A new Greeter object was created!")
g1 = Greeter()
g2 = Greeter()
Expected output:
A new Greeter object was created!
A new Greeter object was created!
Each call to Greeter() triggered __init__() once.
Arguments Must Match
The arguments passed when creating the object must match the parameters of __init__() (not counting self):
u2 = User("sam")
Output:
TypeError: User.__init__() missing 1 required positional argument: 'level'
This is a benefit: Python refuses to create an incomplete object.
Creating Objects Without init()
If a class has no __init__() method, attributes must be assigned manually after each object is created.
Example: Manual Attribute Assignment
class User:
pass
u1 = User()
u1.username = "sam"
u1.level = 2
print(u1.username)
print(u1.level)
Expected output:
sam
2
This works, but it is error-prone and hard to manage in large programs:
- It takes several lines to set up each object.
- It is easy to forget an attribute or misspell one (
u1.usrname = "sam"creates a new, wrong attribute without any error). - Nothing guarantees that every
Userhas the same attributes.
Why init() Is Important
Using __init__():
- Ensures objects are created in a valid state — every object has all its required data from the start.
- Reduces repetitive code — setup logic is written once, in the class.
- Improves readability and reliability — the class definition shows exactly what data each object holds.
Using Default Values in init()
Parameters of __init__() can have default values, which makes them optional when creating objects.
Example: A Default Parameter Value
class Account:
def __init__(self, owner, balance=0):
self.owner = owner
self.balance = balance
a1 = Account("Ravi")
a2 = Account("Meera", 5000)
print(a1.owner, a1.balance)
print(a2.owner, a2.balance)
Expected output:
Ravi 0
Meera 5000
a1does not pass a balance, so the default0is used.a2passes5000, which replaces the default.
Caution: Do not use a mutable value such as
[]or{}as a default. The same object would be shared by every instance created without that argument. UseNoneand create a new list inside__init__()instead:class Cart: def __init__(self, items=None): self.items = items if items is not None else []
Multiple Parameters in init()
__init__() can accept as many parameters as your class needs.
Example: Multiple Attributes
class Employee:
def __init__(self, name, role, department, salary):
self.name = name
self.role = role
self.department = department
self.salary = salary
e1 = Employee("Anita", "Developer", "IT", 75000)
print(e1.name)
print(e1.role)
print(e1.department)
print(e1.salary)
Expected output:
Anita
Developer
IT
75000
For classes with many parameters, keyword arguments make object creation easier to read:
e2 = Employee(name="Kiran", role="Analyst", department="Finance", salary=62000)
Doing More in init(): Validation and Derived Values
__init__() is regular Python code, so it can do more than copy arguments.
class Rectangle:
def __init__(self, width, height):
if width <= 0 or height <= 0:
raise ValueError("Width and height must be positive")
self.width = width
self.height = height
self.area = width * height # A derived attribute
r = Rectangle(4, 5)
print(r.area)
Expected output:
20
- The
ifstatement rejects invalid sizes, so aRectanglecan never be created with a negative width. self.areais calculated from the other values during setup.
Calling Rectangle(-1, 5) raises ValueError: Width and height must be positive.
Common Mistakes
| Mistake | Problem |
|---|---|
Writing __int__ or _init_ | A misspelled name is just an ordinary method; it never runs automatically |
Forgetting self as the first parameter | TypeError when creating the object |
Writing username = username instead of self.username = username | Creates a local variable; the object gets no attribute |
Returning a value from __init__() | TypeError: __init__() should return None |
| Passing the wrong number of arguments | TypeError: missing required positional argument |
Using [] as a default argument | All objects share the same list |
Related Concepts
- Python Classes and Objects — creating classes and instances
- Python self Parameter — what
selfrefers to and why it is needed - Python Class Properties — instance and class attributes in depth
- Python Functions — default and keyword arguments