When you create an object from a class in Python, you usually want it to start life with some data already set — a name, an age, a starting balance. That's exactly what the __init__ method is for. It's a special method that Python calls automatically every time you create a new instance of a class, and it's where you set up that instance's initial state.
__init__ is often called a "constructor" because it constructs — initializes — a new object, even though technically Python has already created the bare object in memory before __init__ runs. Understanding how it works, and what self actually means inside it, is one of the first real hurdles in learning Python classes and objects.
The self Parameter Explained
Every method inside a class, including __init__, takes self as its first parameter. self refers to the specific instance being created or operated on — it's how the method knows which object's data to work with. You don't pass it manually; Python supplies it automatically when you call a method on an object.
class Person:
def __init__(self, name, age):
# self.name and self.age become attributes of THIS instance
self.name = name
self.age = age
# Python automatically passes the new object as 'self'
p1 = Person("Asha", 28)
p2 = Person("Tom", 35)
print(p1.name, p1.age)
print(p2.name, p2.age)
Output:
Asha 28
Tom 35
Notice that p1 and p2 are completely independent — each has its own name and age stored on self, because each call to Person(...) created a fresh instance with its own __init__ run.
Setting Instance Attributes with Defaults
You can give __init__ parameters default values, just like a regular function, so an object can be created with sensible defaults when the caller doesn't specify everything.
class Account:
def __init__(self, owner, balance=0):
self.owner = owner
self.balance = balance
acc = Account("Priya")
print(f"{acc.owner}'s balance is {acc.balance}")
Output:
Priya's balance is 0
Common Mistake: Forgetting self
A very common beginner error is forgetting to write self as the first parameter, or forgetting the self. prefix when assigning an attribute. Without self.name = name, the value is just a local variable inside __init__ that disappears once the method finishes — the object never actually stores it. If you see an AttributeError saying an object "has no attribute," this is usually the cause.
Once you're comfortable with constructors, the natural next step is learning how one class can build on another with inheritance, which also relies heavily on calling a parent class's __init__.
