What Is __init__ in Python Classes?
Learn what Python's __init__ method does, how it differs from __new__, and how to initialize instance attributes correctly, with clear practical examples.
Expected Interview Answer
__init__ is the initializer method Python automatically calls right after an object is created, used to set up the instance's attributes with values passed to the constructor.
When you call `ClassName(args)`, Python first calls `__new__` to create the raw instance (usually inherited from object) and then calls `__init__(self, args)` on that instance to configure it — __init__ itself returns None and never creates the object. `self` refers to the instance being initialized, and any instance attributes assigned inside __init__, like `self.name = name`, become part of that specific object rather than shared across the class.
- Guarantees every new instance starts in a consistent state
- Accepts constructor arguments to customize each instance
- Keeps attribute initialization in one predictable place
- Distinguishes instance attributes from class attributes
- Works with inheritance via super().__init__()
AI Mentor Explanation
__init__ is like a new player's induction session the day they join the squad — kit size, batting order slot, and playing role all get recorded onto that specific player's file the moment they arrive. Every player goes through this same induction, but the details recorded are unique to them, just as __init__ runs for every instance yet sets attribute values specific to that object.
Step-by-Step Explanation
Step 1
Instance creation order
ClassName(args) first calls __new__ to allocate the instance, then calls __init__ on it.
Step 2
self refers to the instance
The first parameter of __init__ is the instance being set up, conventionally named self.
Step 3
Assign instance attributes
self.attr = value inside __init__ creates attributes unique to that instance.
Step 4
No return value
__init__ must return None; it configures the object rather than creating it.
Step 5
Inheritance
A subclass's __init__ typically calls super().__init__(...) to ensure parent setup still runs.
What Interviewer Expects
- Distinguishes __init__ (initializer) from __new__ (constructor)
- Explains self as the instance reference
- Knows __init__ always returns None
- Understands instance vs class attributes
- Mentions super().__init__() in inheritance scenarios
Common Mistakes
- Calling __init__ 'the constructor' without acknowledging __new__
- Returning a value from __init__ (which raises TypeError)
- Confusing class attributes with instance attributes set in __init__
- Forgetting to call super().__init__() in a subclass
Best Answer (HR Friendly)
“__init__ is a special method that runs automatically whenever you create a new object from a class, letting you set up that object's starting data, like its name or initial values, right when it's created.”
Code Example
class Employee:
def __init__(self, name, role):
self.name = name
self.role = role
def __repr__(self):
return f"Employee({self.name!r}, {self.role!r})"
e = Employee("Asha", "Engineer")
print(e) # Employee('Asha', 'Engineer')Follow-up Questions
- What is the difference between __init__ and __new__?
- Why must __init__ return None?
- What is the role of super().__init__() in a subclass?
- How do class attributes differ from instance attributes set in __init__?
- What is __init_subclass__ used for?
MCQ Practice
1. What does __init__ do?
__init__ configures an already-created instance; object creation itself is __new__'s job.
2. What must __init__ return?
__init__ must return None; returning anything else raises a TypeError.
3. What does self refer to inside __init__?
self is the reference to the particular instance whose attributes __init__ is setting up.
Flash Cards
What does __init__ do? — Initializes attributes on a newly created instance.
What must __init__ return? — None — returning anything else raises TypeError.
Which runs first, __new__ or __init__? — __new__ creates the instance, then __init__ initializes it.
How do subclasses extend __init__? — By calling super().__init__() then adding their own setup.