1. Class Methods (@classmethod)
What it is
A method that belongs to the class, not an individual object.
It receives cls instead of self.
When it's used
- Creating alternative constructors
- Tracking class-level data
Example
class Employee:
company = "OpenAI"
count = 0
def __init__(self, name):
self.name = name
Employee.count += 1
@classmethod
def total_employees(cls):
return cls.count
print(Employee.total_employees()) # 0
e1 = Employee("Ali")
e2 = Employee("Sara")
print(Employee.total_employees()) # 2
2. Static Methods (@staticmethod)
What it is
A method inside the class but does NOT access class or instance data.
When used?
- Utility/helper methods
- Math or formatting functions
Example
class MathTool:
@staticmethod
def add(a, b):
return a + b
print(MathTool.add(3, 4))
3. Dunder (Magic) Methods
These are special methods starting with __.
They let you customize how your object behaves.
Common ones
| Magic method | Purpose |
|---|---|
__init__ |
constructor |
__str__ |
object to string |
__len__ |
length |
__add__ |
overloading + operator |
__getitem__ |
indexing |
__call__ |
make object callable |
Example: custom print
class Person:
def __init__(self, name):
self.name = name
def __str__(self):
return f"Person: {self.name}"
p = Person("Ali")
print(p) # Person: Ali
4. Operator Overloading
Allows objects to behave like integers, lists, etc.
Example: add 2 bank accounts
class Account:
def __init__(self, balance):
self.balance = balance
def __add__(self, other):
return Account(self.balance + other.balance)
a1 = Account(500)
a2 = Account(700)
a3 = a1 + a2
print(a3.balance) # 1200
5. Property Decorator (@property)
Allows you to create getter/setter like in Java but more elegant.
Example
class Product:
def __init__(self, price):
self._price = price
@property
def price(self):
return self._price
@price.setter
def price(self, value):
if value >= 0:
self._price = value
else:
raise ValueError("Price can't be negative")
Usage:
p = Product(100)
p.price = 200 # calls setter
print(p.price) # calls getter
6. Inheritance + MRO (Method Resolution Order)
What MRO means
If a class inherits from multiple parents, Python follows a specific order to find methods.
Example
class A:
def show(self): print("A")
class B:
def show(self): print("B")
class C(A, B):
pass
c = C()
c.show() # A
print(C.mro())
C.mro() shows:
[C, A, B, object]
7. Abstract Classes (Interfaces in Python)
Used to force child classes to implement certain methods.
Example
from abc import ABC, abstractmethod
class Payment(ABC):
@abstractmethod
def pay(self):
pass
class CardPayment(Payment):
def pay(self):
print("Payment via card")
8. Composition (HAS-A relationship)
Instead of inheritance (IS-A), we combine objects.
Real-life
A Car has an Engine.
Example
class Engine:
def start(self):
print("Engine starting...")
class Car:
def __init__(self):
self.engine = Engine()
def start(self):
self.engine.start()
c = Car()
c.start()
9. Duck Typing
Python doesn’t care about the type — only if the object has the required behavior.
Example
class Dog:
def speak(self): print("Woof")
class Cat:
def speak(self): print("Meow")
for animal in [Dog(), Cat()]:
animal.speak()
If it acts like a duck, Python treats it as a duck.
10. Making Objects Callable — __call__
Allows objects to be used like functions.
Example
class Multiply:
def __init__(self, n):
self.n = n
def __call__(self, x):
return x * self.n
double = Multiply(2)
print(double(10)) # 20
PyTorch uses this heavily for layers & transforms.
11. Metaclasses (Advanced-Advanced)
Metaclasses = classes that create classes.
For example:
class Meta(type):
def __new__(cls, name, bases, dct):
print("Creating class:", name)
return super().__new__(cls, name, bases, dct)
class Test(metaclass=Meta):
pass
This prints when the class is created.
You rarely need metaclasses until deep framework work.
12. Practical Real-World Example (ML Style)
Here’s how PyTorch builds neural network layers using OOP:
class LinearLayer:
def __init__(self, input_dim, output_dim):
self.weights = [[0]*output_dim for _ in range(input_dim)]
self.bias = [0]*output_dim
def __call__(self, x):
# forward pass (simplified)
return "output vector"
This uses:
- constructor
- composition
- magic method (
__call__)
⭐ Mini Exercises (Advanced)
Send your answers and I’ll review.
1. Create a class Rectangle
- attributes: width, height
- property: area (read-only using
@property) - overload
+to add two rectangles by area
2. Create a class Temperature
- stores Celsius
- provide setter/getter
- convert to Fahrenheit using a method
3. Create a class Logger
- keep count of total logs (use
@classmethod) - method: log(message) → prints message
- property: total_logs
Top comments (0)