🔧 Unit-V: Advanced OOP in Python

Lecture 2: Constructors, Special Methods, and Class Attributes

1. Constructors in Python

Constructors are special methods that are automatically called when an object is created.

1.1 The __init__ Method

class Person: def __init__(self, name, age): self.name = name self.age = age print(f"{name} created!") p = Person("Alice", 30) # Alice created!

1.2 The __new__ Method

class Singleton: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance s1 = Singleton() s2 = Singleton() print(s1 is s2) # True
2. Special Methods

Special methods (dunder methods) allow operator overloading and other functionality.

class Vector: def __init__(self, x, y): self.x = x self.y = y def __add__(self, other): return Vector(self.x + other.x, self.y + other.y) def __str__(self): return f"Vector({self.x}, {self.y})" def __len__(self): return 2 # Always 2D vector v1 = Vector(2, 4) v2 = Vector(1, 3) print(v1 + v2) # Vector(3, 7)
Common Special Methods:
  • __str__: String representation (str(obj))
  • __repr__: Official string representation (repr(obj))
  • __len__: Length of object (len(obj))
  • __getitem__, __setitem__: Indexing (obj[key])
  • __call__: Call as function (obj())
3. Class and Instance Variables
class Employee: # Class variable raise_amount = 1.04 def __init__(self, name, pay): # Instance variables self.name = name self.pay = pay emp1 = Employee("John", 50000) emp2 = Employee("Jane", 60000) # Access class variable print(emp1.raise_amount) # 1.04 # Change class variable (affects all instances) Employee.raise_amount = 1.05 print(emp2.raise_amount) # 1.05
4. Public and Private Members
class BankAccount: def __init__(self, owner, balance=0): self.owner = owner self._balance = balance # Protected (convention) self.__transaction_history = [] # Private (name mangling) def deposit(self, amount): self._balance += amount self.__add_transaction(f"Deposit: +{amount}") def __add_transaction(self, message): self.__transaction_history.append(message) acc = BankAccount("Alice", 1000) print(acc._balance) # Accessible but not recommended # print(acc.__transaction_history) # Error
5. Built-in Class Attributes
class Example: """Example class with built-in attributes.""" def __init__(self): self.value = 42 obj = Example() # Common built-in attributes print(Example.__name__) # 'Example' print(Example.__doc__) # 'Example class with built-in attributes.' print(obj.__dict__) # {'value': 42} print(Example.__module__) # '__main__' print(Example.__bases__) # (,)
6. Practice Exercise

Task: Create a Fraction Class

Implement a Fraction class that supports basic arithmetic operations.

# Your implementation here class Fraction: def __init__(self, numerator, denominator=1): # Add your code here pass # Add special methods for +, -, *, /, ==, <, >, str, repr # Test cases f1 = Fraction(1, 2) f2 = Fraction(3, 4) print(f1 + f2) # Should print 5/4 print(f1 * f2) # Should print 3/8 print(f1 == Fraction(2, 4)) # True