Write a Python class with an __init__ method and show what happens when you call it directly.
__init__ is the initialiser. The interpreter calls it automatically after the object has been created, and its job is to set the object's initial state.
class Rectangle:
def __init__(self, width, height):
if width <= 0 or height <= 0:
raise ValueError("dimensions must be positive")
self.width = width
self.height = height
def area(self):
return self.width * self.height
rect = Rectangle(3, 4)
print(rect.area()) # 12
# __init__ is a normal method - it can be called explicitly
Rectangle.__init__(rect, 5, 6)
print(rect.area()) # 30Calling Rectangle(3, 4) creates the object and then runs __init__ on it. The method itself returns None — its job is the side effect of setting attributes, and the object comes from the class call, not from the return value of __init__.
The last two lines show that __init__ is an ordinary method, not a special hook that only the interpreter can trigger. Calling it directly on an existing object re-initialises it, which works but is rarely what you want; normally you would just assign the attributes.
Two rules about its signature. It must return None, and if you define it you should always accept self as the first parameter. There is also no automatic return value — a class without an __init__ gets a default one that accepts no arguments, which is why Rectangle() with no arguments raises a TypeError rather than creating an empty object.