🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

Python OOP সম্পূর্ণ গাইড 2026: ক্লাস, উত্তরাধিকার এবং ডিজাইন প্যাটার্নস

⏱️6 min read  ·  1,128 words

পাইথনে অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং (OOP) শক্তিশালী, মার্জিত এবং বড় আকারের অ্যাপ্লিকেশন তৈরির জন্য অপরিহার্য। এই সম্পূর্ণ গাইড ক্লাস, উত্তরাধিকার, পলিমরফিজম, জাদু পদ্ধতি, বৈশিষ্ট্য এবং ডিজাইনের প্যাটার্নগুলি কভার করে যা প্রতিটি পাইথন বিকাশকারীকে 2026 সালে জানা উচিত।

ক্লাস এবং উদাহরণ

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 আধুনিক ডেটাক্লাস, স্ট্রাকচারাল টাইপিংয়ের প্রোটোকল এবং পুনরায় ব্যবহারযোগ্য বৈধতার জন্য বর্ণনাকারীর সাথে ঐতিহ্যগত ক্লাস-ভিত্তিক প্যাটার্নগুলিকে একত্রিত করে। এই নিদর্শনগুলি আয়ত্ত করুন এবং আপনি যে কোনও স্কেলে আরও পরিষ্কার, আরও রক্ষণাবেক্ষণযোগ্য পাইথন লিখবেন।

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা