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.
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.
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')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 initializedclass 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 immediatelyclass Bad:
def __init__(self):
return 42 # ❌ TypeError! __init__ must return NoneRule: __init__ MUST return None implicitly or explicitly. Any other return value causes a TypeError.
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.