Ad – 728×90
🏗️ OOP

Python Constructors – __init__ and Object Initialisation

A constructor is special method that runs automatically when an object is created. In Python, the constructor is __init__(). It sets up the initial state of an object by assigning values to instance attributes. Understanding constructors is fundamental to working with classes.

⏱️ 18 min read🎯 Intermediate📅 Updated 2026

The __init__ Method

__init__() is called immediately after an object is created. The first parameter self refers to the newly created instance.

Python
class Dog:
    def __init__(self, name, breed, age):
        self.name = name    # Instance attribute
        self.breed = breed
        self.age = age
        self.tricks = []    # Default empty list

# Creating objects — __init__ runs automatically
rex = Dog("Rex", "German Shepherd", 3)
buddy = Dog("Buddy", "Labrador", 5)

print(rex.name)   # Rex
print(buddy.age)  # 5
▶ Output
Rex 5

Understanding self

self is a reference to the instance being created. It is not a keyword — you could name it anything — but self is the universal Python convention.

Python
class Circle:
    def __init__(self, radius):
        self.radius = radius          # "this circle's radius"
        self.area = 3.14 * radius**2  # Computed on creation

c1 = Circle(5)
c2 = Circle(10)

print(c1.radius, c1.area)   # 5 78.5
print(c2.radius, c2.area)   # 10 314.0
▶ Output
5 78.5 10 314.0

Default Constructor Arguments

Use default values for optional attributes.

Python
class User:
    def __init__(self, username, email, role="user", active=True):
        self.username = username
        self.email = email
        self.role = role
        self.active = active

admin = User("alice", "alice@example.com", role="admin")
guest = User("bob", "bob@example.com")

print(admin.role)   # admin
print(guest.role)   # user (default)
▶ Output
admin user
Ad – 336×280

Validation in __init__

Validate arguments inside __init__ to prevent invalid objects from being created.

Python
class BankAccount:
    def __init__(self, owner, balance=0):
        if not owner:
            raise ValueError("Owner name required")
        if balance < 0:
            raise ValueError("Balance cannot be negative")
        self.owner = owner
        self.balance = balance

try:
    bad = BankAccount("", -100)
except ValueError as e:
    print(f"Error: {e}")

good = BankAccount("Alice", 1000)
print(f"{good.owner}: ${good.balance}")
▶ Output
Error: Owner name required Alice: $1000

Class Attributes vs Instance Attributes

Class attributes are shared across all instances. Instance attributes are unique per object.

Python
class Employee:
    company = "Algorid Limited"   # Class attribute
    employee_count = 0

    def __init__(self, name, salary):
        self.name = name          # Instance attribute
        self.salary = salary
        Employee.employee_count += 1  # Modify class attr

e1 = Employee("Alice", 75000)
e2 = Employee("Bob", 80000)

print(e1.company)          # Algorid Limited (class attr)
print(Employee.employee_count)  # 2
▶ Output
Algorid Limited 2