⏱️6 min read · 1,128 words
পাইথনে অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং (OOP) শক্তিশালী, মার্জিত এবং বড় আকারের অ্যাপ্লিকেশন তৈরির জন্য অপরিহার্য। এই সম্পূর্ণ গাইড ক্লাস, উত্তরাধিকার, পলিমরফিজম, জাদু পদ্ধতি, বৈশিষ্ট্য এবং ডিজাইনের প্যাটার্নগুলি কভার করে যা প্রতিটি পাইথন বিকাশকারীকে 2026 সালে জানা উচিত।
📋 Table of Contents
ক্লাস এবং উদাহরণ
class BankAccount:
# Class variable (shared by all instances)
interest_rate = 0.05
_total_accounts = 0
def __init__(self, owner: str, initial_balance: float = 0.0):
self.owner = owner # instance variable
self._balance = initial_balance # convention: protected
self.__id = BankAccount._total_accounts # private (name-mangled)
BankAccount._total_accounts += 1
@property
def balance(self) -> float:
return self._balance
@balance.setter
def balance(self, amount: float) -> None:
if amount < 0:
raise ValueError("Balance cannot be negative")
self._balance = amount
def deposit(self, amount: float) -> "BankAccount":
if amount <= 0:
raise ValueError(f"Deposit amount must be positive, got {amount}")
self._balance += amount
return self # enables method chaining
def withdraw(self, amount: float) -> "BankAccount":
if amount > self._balance:
raise ValueError("Insufficient funds")
self._balance -= amount
return self
def apply_interest(self) -> "BankAccount":
self._balance *= (1 + self.interest_rate)
return self
@classmethod
def get_total_accounts(cls) -> int:
return cls._total_accounts
@staticmethod
def is_valid_amount(amount: float) -> bool:
return amount > 0
def __str__(self) -> str:
return f"BankAccount(owner={self.owner!r}, balance={self._balance:.2f})"
def __repr__(self) -> str:
return f"BankAccount(owner={self.owner!r}, balance={self._balance!r})"
# Usage
account = BankAccount("Alice", 1000.0)
account.deposit(500).apply_interest().withdraw(200) # method chaining
print(account) # BankAccount(owner='Alice', balance=1365.00)
print(BankAccount.get_total_accounts()) # 1
উত্তরাধিকার এবং পলিমরফিজম
from abc import ABC, abstractmethod
from typing import Protocol
# Abstract base class
class Animal(ABC):
def __init__(self, name: str, age: int):
self.name = name
self.age = age
@abstractmethod
def speak(self) -> str:
pass
@abstractmethod
def move(self) -> str:
pass
def __str__(self) -> str:
return f"{type(self).__name__}(name={self.name!r})"
class Dog(Animal):
def speak(self) -> str:
return f"{self.name} says: Woof!"
def move(self) -> str:
return f"{self.name} runs"
def fetch(self, item: str) -> str:
return f"{self.name} fetched the {item}!"
class Cat(Animal):
def speak(self) -> str:
return f"{self.name} says: Meow!"
def move(self) -> str:
return f"{self.name} slinks"
# Polymorphism
animals: list[Animal] = [Dog("Rex", 3), Cat("Whiskers", 5), Dog("Buddy", 2)]
for animal in animals:
print(animal.speak()) # each calls its own speak()
print(animal.move())
# isinstance checks
for animal in animals:
if isinstance(animal, Dog):
print(animal.fetch("ball"))
# Multiple inheritance with MRO
class Flyable:
def fly(self) -> str:
return f"{self.name} flies" # type: ignore
class FlyingDog(Dog, Flyable):
def move(self) -> str:
return f"{self.name} runs and flies!"
super_dog = FlyingDog("Krypto", 4)
print(super_dog.fly()) # from Flyable
print(FlyingDog.__mro__) # Method Resolution Order
জাদু পদ্ধতি (ডান্ডার পদ্ধতি)
from functools import total_ordering
@total_ordering # auto-generates __le__, __lt__, __ge__, __gt__ from __eq__ and __lt__
class Temperature:
def __init__(self, celsius: float):
self._celsius = celsius
@classmethod
def from_fahrenheit(cls, f: float) -> "Temperature":
return cls((f - 32) * 5 / 9)
@property
def celsius(self) -> float:
return self._celsius
@property
def fahrenheit(self) -> float:
return self._celsius * 9 / 5 + 32
# String representation
def __str__(self) -> str:
return f"{self._celsius:.1f}C"
def __repr__(self) -> str:
return f"Temperature({self._celsius!r})"
# Comparison
def __eq__(self, other: object) -> bool:
if not isinstance(other, Temperature):
return NotImplemented
return self._celsius == other._celsius
def __lt__(self, other: "Temperature") -> bool:
return self._celsius < other._celsius
# Arithmetic
def __add__(self, other: "Temperature") -> "Temperature":
return Temperature(self._celsius + other._celsius)
def __mul__(self, factor: float) -> "Temperature":
return Temperature(self._celsius * factor)
# Container protocol
def __len__(self) -> int:
return 1
# Context manager protocol
def __enter__(self) -> "Temperature":
print(f"Measuring temperature: {self}")
return self
def __exit__(self, exc_type, exc_val, exc_tb) -> bool:
print("Done measuring")
return False # don't suppress exceptions
# Usage
t1 = Temperature(20)
t2 = Temperature.from_fahrenheit(98.6)
print(sorted([t2, t1])) # uses __lt__
print(t1 + t2) # uses __add__
print(t1 < t2) # True (20 < 37)
with Temperature(37.0) as body_temp:
print(f"Normal? {body_temp.celsius == 37.0}")
বৈশিষ্ট্য এবং বর্ণনাকারী
class Validator:
def __set_name__(self, owner, name: str):
self.name = name
self.private_name = f"_{name}"
def __get__(self, obj, objtype=None):
if obj is None:
return self
return getattr(obj, self.private_name, None)
def __set__(self, obj, value):
self.validate(value)
setattr(obj, self.private_name, value)
def validate(self, value):
pass # override in subclasses
class PositiveNumber(Validator):
def validate(self, value):
if not isinstance(value, (int, float)) or value <= 0:
raise ValueError(f"{self.name} must be a positive number, got {value!r}")
class NonEmptyString(Validator):
def validate(self, value):
if not isinstance(value, str) or not value.strip():
raise ValueError(f"{self.name} must be a non-empty string, got {value!r}")
class Product:
name = NonEmptyString()
price = PositiveNumber()
quantity = PositiveNumber()
def __init__(self, name: str, price: float, quantity: int):
self.name = name # triggers NonEmptyString.__set__
self.price = price # triggers PositiveNumber.__set__
self.quantity = quantity
@property
def total_value(self) -> float:
return self.price * self.quantity
# Usage
product = Product("Widget", 9.99, 100)
print(product.total_value) # 999.0
product.price = -5 # raises ValueError
পাইথনে ডিজাইন প্যাটার্ন
# Observer pattern
from __future__ import annotations
from typing import Protocol
class Observer(Protocol):
def update(self, event: str, data: dict) -> None: ...
class EventEmitter:
def __init__(self):
self._listeners: dict[str, list[Observer]] = {}
def on(self, event: str, listener: Observer) -> None:
self._listeners.setdefault(event, []).append(listener)
def off(self, event: str, listener: Observer) -> None:
self._listeners.get(event, []).remove(listener)
def emit(self, event: str, data: dict = {}) -> None:
for listener in self._listeners.get(event, []):
listener.update(event, data)
# Strategy pattern
class SortStrategy(Protocol):
def sort(self, data: list) -> list: ...
class BubbleSort:
def sort(self, data: list) -> list:
data = data.copy()
n = len(data)
for i in range(n):
for j in range(0, n-i-1):
if data[j] > data[j+1]:
data[j], data[j+1] = data[j+1], data[j]
return data
class Sorter:
def __init__(self, strategy: SortStrategy):
self.strategy = strategy
def sort(self, data: list) -> list:
return self.strategy.sort(data)
sorter = Sorter(BubbleSort())
print(sorter.sort([3, 1, 4, 1, 5, 9]))
ডেটাক্লাস – আধুনিক পাইথন ওওপি
from dataclasses import dataclass, field
from typing import ClassVar
@dataclass
class Point:
x: float
y: float
def distance_to(self, other: "Point") -> float:
return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5
def __add__(self, other: "Point") -> "Point":
return Point(self.x + other.x, self.y + other.y)
@dataclass(order=True, frozen=True) # immutable + comparable
class Version:
major: int
minor: int
patch: int = 0
VERSION_PATTERN: ClassVar[str] = r"(\d+)\.(\d+)\.?(\d+)?"
def __str__(self) -> str:
return f"{self.major}.{self.minor}.{self.patch}"
p1, p2 = Point(0, 0), Point(3, 4)
print(p1.distance_to(p2)) # 5.0
v1, v2 = Version(1, 2, 3), Version(2, 0, 0)
print(sorted([v2, v1])) # [Version(1,2,3), Version(2,0,0)]
2026 সালে Python OOP আধুনিক ডেটাক্লাস, স্ট্রাকচারাল টাইপিংয়ের প্রোটোকল এবং পুনরায় ব্যবহারযোগ্য বৈধতার জন্য বর্ণনাকারীর সাথে ঐতিহ্যগত ক্লাস-ভিত্তিক প্যাটার্নগুলিকে একত্রিত করে। এই নিদর্শনগুলি আয়ত্ত করুন এবং আপনি যে কোনও স্কেলে আরও পরিষ্কার, আরও রক্ষণাবেক্ষণযোগ্য পাইথন লিখবেন।
🔗 Share this article
✍️ Leave a Comment