Learning

Constructors & Initialization

Constructors & Initialization

init (The Initializer)

python
class User: def __init__(self, username, email): # At this point, the object ALREADY EXISTS in memory self.username = username self.email = email u = User('alice', 'a@test.com')

Key point: __init__ does NOT create the object. It initializes an already-created object.

new (The Actual Constructor)

python
class Singleton: _instance = None def __new__(cls, *args, **kwargs): # __new__ CREATES the instance if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance # Returns the created object def __init__(self, name): self.name = name s1 = Singleton('A') s2 = Singleton('B') print(s1 is s2) # True (same object) print(s1.name) # 'B' (__init__ runs AGAIN on the existing object!)

Flow: __new__ creates → __init__ initializes.

Parameterized Constructors

python
class Point: def __init__(self, x=0, y=0): self.x = x self.y = y # Alternative constructors using classmethod @classmethod def from_tuple(cls, coords): return cls(coords[0], coords[1]) @classmethod def from_string(cls, str_coords): x, y = map(float, str_coords.split(',')) return cls(x, y) p1 = Point(10, 20) p2 = Point.from_tuple((30, 40)) p3 = Point.from_string('50.5,60.5')

Constructor Chaining with super()

python
class Employee: def __init__(self, name, salary): self.name = name self.salary = salary print('Employee initialized') class Manager(Employee): def __init__(self, name, salary, department): # Call parent's __init__ FIRST super().__init__(name, salary) self.department = department print('Manager initialized') m = Manager('Alice', 90000, 'Engineering') # Output: # Employee initialized # Manager initialized

Handling Initialization Errors

python
class Age: def __init__(self, value): if not isinstance(value, int): raise TypeError('Age must be an integer') if value < 0 or value > 150: raise ValueError('Age out of range') self.value = value # a = Age(-5) # Raises ValueError immediately

init Return Value

python
class Bad: def __init__(self): return 42 # ❌ TypeError! __init__ must return None

Rule: __init__ MUST return None implicitly or explicitly. Any other return value causes a TypeError.

Key Rules
  • •__new__ creates the object (allocates memory), __init__ initializes it (sets attributes)
  • •Always call super().__init__() in a subclass BEFORE setting subclass-specific attributes
  • •Use @classmethod for alternative constructors (like from_string) instead of overloading __init__
  • •__init__ MUST NOT return anything other than None — it's an initializer, not a factory
  • •Be careful with Singletons: __init__ runs every time you call ClassName(), even if __new__ returns an existing object
Your Task

Create a `Person` class with `name` and `age`. Create an `Employee(Person)` class that adds `employee_id` and `salary`. Employee's `__init__` MUST use `super()` to initialize name and age. Add a `@classmethod` to Person called `from_birth_year(cls, name, birth_year)` that calculates age from current year. Create one Employee manually and one Person using the classmethod.

EditorPython · JSX
PreviewUpdates on Run Tests
Loading preview…
Tests
Should define Person class
Should define from_birth_year as classmethod
Should define Employee inheriting from Person
Should use super().__init__ in Employee
Should call from_birth_year in test
Should import datetime