Modern Python 3.12+ చాప్టర్ 22 / 25 Phase 05: OOP & Advanced 2026 Edition

22. ఆబ్జెక్ట్ ఓరియెంటెడ్ ప్రోగ్రామింగ్ (OOP) బేసిక్స్ — Classes, Objects, __init__ & self

📌 Covered in this chapter: OOP Mental Model vs Procedural • Class Blueprint & Object Instantiation • __init__ Constructor Lifecycle • The Mystery of self • Instance vs Class Attributes & __dict__ • Instance, @classmethod, @staticmethod • Autonomous Fleet Management Capstone
సాఫ్ట్‌వేర్ అభివృద్ధిలో నిజ జీవిత సమస్యలను (Real-world Entities) కంప్యూటర్ ప్రోగ్రామ్‌గా మలచడానికి అత్యంత ప్రజాదరణ పొందిన పద్ధతి ఆబ్జెక్ట్ ఓరియెంటెడ్ ప్రోగ్రామింగ్ (Object-Oriented Programming - OOP). ఇప్పటివరకు మనం వేరియబుల్స్, లిస్టులు మరియు ఫంక్షన్ల ద్వారా కోడ్ రాశాము (ఇది Procedural Programming). అయితే పెద్ద స్థాయి అప్లికేషన్లు, గేమింగ్ ఇంజిన్లు, వెబ్ ఫ్రేమ్‌వర్కులు (Django, FastAPI), AI ఆర్కిటెక్చర్లు (PyTorch, TensorFlow) నిర్మించేటప్పుడు డేటాను (State) మరియు ఆ డేటాపై పనిచేసే ఫంక్షన్లను (Behavior) ఒకే గూటికి చేర్చడం అనివార్యం. ఈ అధ్యాయంలో క్లాస్ అంటే ఏమిటి, మెమరీలో ఆబ్జెక్ట్ ఎలా పుడుతుంది, __init__ కన్‌స్ట్రక్టర్ అంతర్గత చక్రం ఏమిటి, పైథాన్‌లో self పారామీటర్ ఎందుకు తప్పనిసరిగా ఉండాలి, మరియు క్లాస్ మెథడ్స్, స్టాటిక్ మెథడ్స్ మధ్య సూక్ష్మ వ్యత్యాసాలను ప్రాక్టికల్ విజువల్స్‌తో లోతుగా శోధిద్దాం.

1 ప్రొసీజరల్ వర్సెస్ ఆబ్జెక్ట్ ఓరియెంటెడ్ ప్రోగ్రామింగ్ (OOP Mental Model)

పైథాన్ ఒక మల్టీ-పారడైమ్ (Multi-paradigm) ప్రోగ్రామింగ్ లాంగ్వేజ్. మీరు ఫంక్షనల్ శైలిలో కోడ్ రాయవచ్చు, ప్రొసీజరల్ శైలిలో రాయవచ్చు, లేదా ఆబ్జెక్ట్ ఓరియెంటెడ్ పద్ధతిలో రూపొందించవచ్చు. ఈ రెండింటి మధ్య ప్రాథమిక తేడాను గ్రహించడం సాఫ్ట్‌వేర్ ఆర్కిటెక్ట్‌గా మారడానికి మొదటి మెట్టు:

ఫీచర్ ప్రొసీజరల్ ప్రోగ్రామింగ్ (C / Basic Python) ఆబ్జెక్ట్ ఓరియెంటెడ్ ప్రోగ్రామింగ్ (OOP)
కేంద్ర బిందువు ఫంక్షన్లు మరియు ఆపరేషన్ల క్రమం (Actions & Algorithms). డేటా మరియు రియల్-వరల్డ్ ఎంటిటీలు (Objects & State).
డేటా భద్రత డేటా గ్లోబల్‌గా లేదా బహిరంగంగా ఉంటుంది; ఏ ఫంక్షన్ అయినా మార్చవచ్చు. డేటా ఆబ్జెక్ట్ లోపల ఎన్‌క్యాప్సులేట్ చేయబడి బయటి జోక్యం నుండి రక్షించబడుతుంది.
స్కేలబిలిటీ & మెయింటెనెన్స్ కోడ్ సైజు పెరిగేకొద్దీ ఫంక్షన్ల మధ్య గందరగోళం ("స్పాఘెట్టి కోడ్") ఏర్పడుతుంది. మాడ్యులారిటీ, కోడ్ పునర్వినియోగం (Reusability), మరియు క్లీన్ ఆర్కిటెక్చర్ సాధ్యమవుతాయి.

2 క్లాస్ (Class) మరియు ఆబ్జెక్ట్ (Object) — Blueprint vs Building

బిగినర్స్ ఎక్కువగా గందరగోళానికి గురయ్యే అంశం: క్లాస్‌కు మరియు ఆబ్జెక్ట్‌కు మధ్య వ్యత్యాసం ఏమిటి?

ఆర్కిటెక్చర్ అనాలజీ (Real-world Visual Model):

క్లాస్ (Class) అనేది కేవలం బ్లూప్రింట్ (డిజైన్ నమూనా): ఒక ఇంటిని నిర్మించడానికి ఆర్కిటెక్ట్ కాగితంపై గీసిన ఇంజనీరింగ్ ప్లాన్ క్లాస్ వంటిది. ఆ ప్లాన్ కాగితం మాత్రమే; మీరు ఆ ప్లాన్‌లో నివసించలేరు, అది భూమిపై ఎటువంటి స్థలాన్ని (RAM మెమరీని) ఆక్రమించదు. అందులో బెడ్‌రూమ్ ఎక్కడ ఉండాలి, తలుపులు ఎలా ఉండాలి అనే వర్ణనలు మాత్రమే ఉంటాయి.

ఆబ్జెక్ట్ (Object లేదా Instance) అనేది నిజమైన భవనం: ఆ బ్లూప్రింట్‌ను ఆధారంగా చేసుకుని కాంక్రీట్, ఇటుకలతో భూమిపై నిర్మించిన వాస్తవమైన ఇల్లు ఆబ్జెక్ట్. ఒకే బ్లూప్రింట్ ఆధారంగా మీరు 10 వేర్వేరు రంగులు, వేర్వేరు ఫర్నిచర్ ఉన్న 10 ఇళ్లను నిర్మించవచ్చు. కంప్యూటర్‌లో ప్రతి ఇల్లు ర్యామ్ (RAM) లో ఒక ప్రత్యేకమైన మెమరీ అడ్రస్‌ను (Memory Location) కలిగి ఉంటుంది.

3 క్లాస్ డిక్లరేషన్ & ఇన్స్టాన్షియేషన్ మెకానిక్స్

పైథాన్‌లో క్లాస్‌ను డిక్లేర్ చేయడానికి class అనే రిజర్వ్‌డ్ కీవర్డ్‌ను ఉపయోగిస్తాము. PEP 8 ప్రమాణాల ప్రకారం క్లాస్ పేర్లను ఎల్లప్పుడూ PascalCase (ప్రతి పదం మొదటి అక్షరం క్యాపిటల్) లో రాయాలి (ఉదా: BankAccount, NetworkConnectionManager):

4 __init__ మెథడ్ డీప్ డైవ్ (Constructor Lifecycle & __new__)

ఆబ్జెక్ట్ సృష్టించబడిన వెంటనే దానికి అవసరమైన ప్రారంభ విలువలను (Initial State) కేటాయించడానికి పైథాన్‌లో ప్రత్యేకమైన డండర్ (Double Underscore) మెథడ్ __init__ ను వాడతాము. దీనిని సాంప్రదాయ ప్రోగ్రామింగ్‌లో Constructor అని పిలుస్తారు:

ఆబ్జెక్ట్ సృష్టి ప్రయాణం: __new__ vs __init__ అంతర్గత రహస్యం:

చాలామంది __init__ ఆబ్జెక్ట్‌ను సృష్టిస్తుందని అనుకుంటారు. కానీ వాస్తవానికి పైథాన్ అంతర్గతంగా రెండు వేర్వేరు దశలను నిర్వహిస్తుంది:

  1. దశ 1: __new__(cls, ...) (ది క్రియేటర్): ఇది స్టాటిక్ మెథడ్. ఇది ఆపరేటింగ్ సిస్టమ్ నుండి కొత్త మెమరీ బ్లాక్‌ను కేటాయించి, ఒక ఖాళీ "రా ఆబ్జెక్ట్" (Uninitialized Instance) ను సృష్టించి రిటర్న్ చేస్తుంది. Singleton Design Pattern వంటి ఆర్కిటెక్చర్లలో ఆబ్జెక్ట్ సృష్టిని నియంత్రించడానికి దీనిని ఓవర్‌రైడ్ చేస్తారు.
  2. దశ 2: __init__(self, ...) (ది ఇనిషియలైజర్): __new__ సృష్టించిన ఆబ్జెక్ట్‌ను మొదటి పారామీటర్ (self) గా అందుకుని, దానికి అవసరమైన వేరియబుల్స్ (పేరు, వయస్సు, శాలరీ) ను అమర్చుతుంది. ఇది ఎల్లప్పుడూ None మాత్రమే రిటర్న్ చేయాలి.

5 self పారామీటర్ అంతర్గత రహస్యం (Method Binding Mechanics)

పైథాన్ క్లాసులలో ప్రతి ఇన్స్టాన్స్ మెథడ్ మొదటి ఆర్గ్యుమెంట్‌గా self ఎందుకు ఉండాలి? C++ లేదా Java లో this కీవర్డ్ కనిపించకుండా దాగి ఉంటుంది (Implicit), కానీ పైథాన్‌లో Explicit is better than implicit (ది జెన్ ఆఫ్ పైథాన్ సూత్రం) ప్రకారం self స్పష్టంగా మొదటి పారామీటర్‌గా ఉండాలి:

⚙️ పైథాన్ రన్‌టైమ్ తెరవెనుక ఏమి చేస్తుంది?
మీరు కోడ్‌లో my_car.drive(60) అని పిలిచినప్పుడు, పైథాన్ ఇంటర్‌ప్రీటర్ దానిని వెనువెంటనే Car.drive(my_car, 60) గా మారుస్తుంది! అంటే క్లాస్ యొక్క సాధారణ ఫంక్షన్‌కు మీరు పిలిచిన ఆబ్జెక్ట్ రెఫరెన్స్‌నే (my_car) మొదటి ఆర్గ్యుమెంట్‌గా పాస్ చేస్తుంది. ఆ కరెంట్ ఆబ్జెక్ట్‌ను పట్టుకునే పారామీటరే self.

6 ఇన్స్టాన్స్ వేరియబుల్స్ vs క్లాస్ వేరియబుల్స్ & __slots__ ఆప్టిమైజేషన్

పైథాన్‌లో వేరియబుల్స్ ఏ స్థాయిలో డిక్లేర్ చేయబడ్డాయో అనేదానిపై వాటి ప్రవర్తన మరియు మెమరీ వినియోగం ఆధారపడి ఉంటుంది:

ఫీచర్ ఇన్స్టాన్స్ వేరియబుల్ (Instance Attribute) క్లాస్ వేరియబుల్ (Class Attribute)
డిక్లరేషన్ లొకేషన్ __init__ లేదా మెథడ్స్ లోపల self.name తో క్లాస్ బాడీలో ఏ మెథడ్ బయటైనా నేరుగా
మెమరీ షేరింగ్ ప్రతి ఆబ్జెక్ట్‌కు స్వంత ప్రత్యేక మెమరీ కాపీ ఉంటుంది అన్ని ఆబ్జెక్టులు ఒకే ఒక కాపీని పంచుకుంటాయి (Shared)
యాక్సెస్ పద్ధతి object.attribute ClassName.attribute లేదా object.attribute
ఇంటర్నల్ స్టోరేజ్ ఆబ్జెక్ట్ యొక్క self.__dict__ లో నిల్వ ఉంటుంది క్లాస్ యొక్క ClassName.__dict__ లో నిల్వ ఉంటుంది
🚀 ప్రో టిప్ — మెమరీ ఆప్టిమైజేషన్ with __slots__: పైథాన్‌లో ప్రతి సాధారణ ఆబ్జెక్ట్ డైనమిక్ అట్రిబ్యూట్ల కోసం లోపల ఒక డిక్షనరీని (__dict__) నిర్వహిస్తుంది. దీనివల్ల వేల కొద్దీ ఆబ్జెక్టులు ఉన్నప్పుడు భారీగా RAM వృథా అవుతుంది. మీరు క్లాస్‌లో __slots__ = ('name', 'salary') అని డిఫైన్ చేస్తే, పైథాన్ __dict__ ను తొలగించి స్థిరమైన C-స్ట్రక్చర్ శైలిలో మెమరీని కేటాయిస్తుంది. దీనివల్ల మెమరీ వినియోగం దాదాపు 40% నుండి 50% వరకు తగ్గుతుంది!

7 ఇన్స్టాన్స్ మెథడ్స్ (Instance Methods)

క్లాస్‌లో డిఫాల్ట్‌గా రాసే మెథడ్స్ అన్నీ ఇన్స్టాన్స్ మెథడ్లే. వీటి మొదటి పారామీటర్ ఎల్లప్పుడూ self. ఇవి నిర్దిష్ట ఆబ్జెక్ట్ యొక్క స్టేట్‌ను చదవగలవు, విలువలను మార్చగలవు, అలాగే ఇతర ఇన్స్టాన్స్ మెథడ్లను పిలవగలవు. ఉదాహరణకు ఒక బ్యాంకింగ్ అకౌంట్‌లో డిపాజిట్ చేయడం లేదా విత్‌డ్రా చేయడం వంటి చర్యలు ఆ నిర్దిష్ట వ్యక్తి బ్యాలెన్స్‌ను మాత్రమే మార్చాలి కాబట్టి అవి ఇన్స్టాన్స్ మెథడ్స్‌గా రూపొందించబడతాయి.

8 క్లాస్ మెథడ్స్ (@classmethod & cls పారామీటర్)

కొన్ని సందర్భాలలో మనకు ఒక నిర్దిష్ట ఆబ్జెక్ట్ డేటాతో పని ఉండదు; బదులుగా మొత్తం క్లాస్ వేరియబుల్స్‌ను మార్చాల్సి ఉంటుంది లేదా Alternative Constructors (వివిధ ఫార్మాట్ల డేటా నుండి ఆబ్జెక్టులను సృష్టించే ఫ్యాక్టరీ మెథడ్స్) నిర్మించాల్సి ఉంటుంది. దీని కోసం @classmethod డెకరేటర్‌ను మరియు మొదటి పారామీటర్‌గా cls (క్లాస్ రెఫరెన్స్) ను ఉపయోగిస్తాము:

9 స్టాటిక్ మెథడ్స్ (@staticmethod) & మెథడ్స్ త్రయం సమగ్ర పోలిక

ఒక మెథడ్‌కు ఆబ్జెక్ట్ డేటాతో (self) పని లేదు, మరియు క్లాస్ వేరియబుల్స్‌తో (cls) కూడా పని లేదు; కానీ లాజికల్‌గా ఆ క్లాస్‌కు సంబంధించిన యుటిలిటీ లేదా వాలిడేషన్ ఫంక్షన్ అయితే, దానిని @staticmethod గా డిక్లేర్ చేస్తాము:

లక్షణం Instance Method Class Method (@classmethod) Static Method (@staticmethod)
మొదటి పారామీటర్ self (ఆబ్జెక్ట్ రెఫరెన్స్) cls (క్లాస్ రెఫరెన్స్) ఏదీ లేదు (సాధారణ పారామీటర్లు మాత్రమే)
స్టేట్ మోడిఫికేషన్ ఆబ్జెక్ట్ స్టేట్‌ను మార్చగలదు క్లాస్ స్టేట్‌ను మార్చగలదు ఆబ్జెక్ట్ లేదా క్లాస్ స్టేట్‌ను మార్చలేదు
వాడాల్సిన ప్రధాన సందర్భం బిజినెస్ బిహేవియర్ & డేటా ఆపరేషన్లు ఫ్యాక్టరీ మెథడ్స్, ఆల్టర్నేటివ్ కన్‌స్ట్రక్టర్లు వాలిడేషన్, యుటిలిటీ గణనలు, హెల్పర్ లాజిక్

10 కోడ్ డెమో 1: బ్యాంకింగ్ అకౌంట్ మోడలింగ్ (Complete Implementation)

డిపాజిట్, విత్‌డ్రా, మరియు బ్యాలెన్స్ ఎంక్వైరీతో కూడిన పూర్తి బ్యాంకింగ్ అకౌంట్ క్లాస్‌ను లైవ్‌గా పరిశీలిద్దాం:

01_bank_account_oop.py
# చాప్టర్ 22: బ్యాంకింగ్ అకౌంట్ OOP మోడల్
class BankAccount:
    bank_name = "State Bank of Telugu"
    interest_rate = 0.04  # 4% వార్షిక వడ్డీ

    def __init__(self, account_no: str, holder_name: str, opening_balance: float = 1000.0):
        self.account_no = account_no
        self.holder_name = holder_name
        self.balance = opening_balance
        self.transactions = []

    def deposit(self, amount: float):
        if amount <= 0:
            print("❌ డిపాజిట్ మొత్తం పాజిటివ్‌గా ఉండాలి!")
            return False
        self.balance += amount
        self.transactions.append(f"+ ₹{amount:,.2f} జమ చేయబడింది")
        print(f"✅ ₹{amount:,.2f} డిపాజిట్ విజయవంతం. ప్రస్తుత బ్యాలెన్స్: ₹{self.balance:,.2f}")
        return True

    def withdraw(self, amount: float):
        if amount > self.balance:
            print(f"❌ విత్‌డ్రా విఫలం! ఖాతాలో తగినంత నగదు లేదు (బ్యాలెన్స్: ₹{self.balance:,.2f})")
            return False
        self.balance -= amount
        self.transactions.append(f"- ₹{amount:,.2f} డ్రా చేయబడింది")
        print(f"💸 ₹{amount:,.2f} విత్‌డ్రా సక్సెస్. మిగిలిన బ్యాలెన్స్: ₹{self.balance:,.2f}")
        return True

    def statement(self):
        print(f"
--- {BankAccount.bank_name} స్టేట్‌మెంట్: {self.holder_name} ({self.account_no}) ---")
        for tx in self.transactions:
            print("  *", tx)
        print(f"నికర నిల్వ (Net Balance): ₹{self.balance:,.2f}
")

# ఆబ్జెక్టులను సృష్టించి పరీక్షిద్దాం
acc1 = BankAccount("SB-10928", "రమేష్ వర్మ", 15000.0)
acc1.deposit(5000.0)
acc1.withdraw(3500.0)
acc1.withdraw(25000.0)  # విఫలమవుతుంది
acc1.statement()

11 కోడ్ డెమో 2: కార్పొరేట్ ఎంప్లాయ్ మేనేజర్ with @classmethod & @staticmethod

క్లాస్ మెథడ్స్ మరియు స్టాటిక్ మెథడ్స్ రియల్-వరల్డ్ సాఫ్ట్‌వేర్‌లో డేటా పార్సింగ్ మరియు బిజినెస్ రూల్స్‌కు ఎలా ఉపయోగపడతాయో చూద్దాం:

02_employee_factory_methods.py
import re

class Employee:
    company_name = "Hyderabad Tech Innovators"
    total_employees = 0

    def __init__(self, emp_id: str, name: str, role: str, salary: float):
        self.emp_id = emp_id
        self.name = name
        self.role = role
        self.salary = salary
        Employee.total_employees += 1

    # ఇన్స్టాన్స్ మెథడ్
    def apply_bonus(self, percentage: float):
        bonus_amount = self.salary * (percentage / 100)
        self.salary += bonus_amount
        print(f"🎉 {self.name} కి {percentage}% బోనస్ (₹{bonus_amount:,.2f}) లభించింది. కొత్త శాలరీ: ₹{self.salary:,.2f}")

    # క్లాస్ మెథడ్: ఆల్టర్నేటివ్ కన్‌స్ట్రక్టర్ (CSV డేటా నుండి ఆబ్జెక్ట్ సృష్టి)
    @classmethod
    def from_csv_line(cls, csv_line: str):
        parts = [p.strip() for p in csv_line.split(",")]
        emp_id, name, role, salary_str = parts
        return cls(emp_id, name, role, float(salary_str))

    # స్టాటిక్ మెథడ్: స్వతంత్ర ఈమెయిల్ వాలిడేటర్
    @staticmethod
    def is_valid_corp_email(email: str) -> bool:
        pattern = r"^[a-zA-Z0-9_.+-]+@techinnovators.com$"
        return bool(re.match(pattern, email))

# పరీక్షించడం
emp1 = Employee("EMP01", "సరిత", "Senior Architect", 125000.0)
emp2 = Employee.from_csv_line("EMP02, విక్రమ్ రాజ్, DevOps Lead, 110000.0")

emp1.apply_bonus(10)
print(f"మొత్తం ఉద్యోగుల సంఖ్య: {Employee.total_employees}")
print("ఈమెయిల్ సరియైనదా?:", Employee.is_valid_corp_email("vikram@techinnovators.com"))
print("వ్యక్తిగత జీమెయిల్ సరియైనదా?:", Employee.is_valid_corp_email("vikram@gmail.com"))

12 కామన్ బిగినర్స్ మిస్టేక్స్ & ప్రొడక్షన్ బెస్ట్ ప్రాక్టీసెస్

13 రియల్-వరల్డ్ ప్రాజెక్ట్: "Smart Autonomous Vehicle Fleet Management Engine"

ఈ అధ్యాయంలో నేర్చుకున్న క్లాసెస్, ఆబ్జెక్ట్స్, __init__ కన్‌స్ట్రక్టర్, క్లాస్ అట్రిబ్యూట్స్, ఇన్స్టాన్స్ మెథడ్స్, @classmethod మరియు @staticmethod లన్నింటినీ రంగరించి — ఒక పూర్తి స్థాయి Smart Autonomous Vehicle Fleet Management System ను నిర్మిద్దాం! ఈ ఇంజిన్ వాహనాల బ్యాటరీ స్థితి, ప్రయాణ కిలోమీటర్లు, సర్వీసింగ్ అలర్టులు మరియు ఫ్లీట్ సారాంశ విశ్లేషణలను సమగ్రంగా నిర్వహిస్తుంది.

03_autonomous_fleet_management_engine.py
# =====================================================================
# చాప్టర్ 22 ప్రాజెక్ట్: Smart Autonomous Vehicle Fleet Engine
# ఫీచర్స్: Classes & Objects, Class Attributes vs Instance Attributes,
#          Alternative Factory Constructors (@classmethod), Utility Validators (@staticmethod)
# =====================================================================
import datetime

class AutonomousVehicle:
    fleet_name = "Cyberabad Smart EV Mobility"
    fleet_registry = []
    min_battery_threshold = 15.0  # 15% కన్నా తక్కువ ఉంటే రైడ్ ఆగిపోతుంది

    def __init__(self, vehicle_id: str, model: str, battery_percentage: float = 100.0):
        self.vehicle_id = vehicle_id
        self.model = model
        self.battery_percentage = max(0.0, min(100.0, battery_percentage))
        self.odometer_km = 0.0
        self.status = "IDLE"  # IDLE, IN_TRANSIT, CHARGING, MAINTENANCE
        self.trip_log = []
        
        # ఫ్లీట్ రిజిస్ట్రీలో ఈ ఆబ్జెక్ట్‌ను నమోదు చేయడం
        AutonomousVehicle.fleet_registry.append(self)

    # 1. ఇన్స్టాన్స్ మెథడ్: ట్రిప్ రన్ చేయడం
    def execute_trip(self, distance_km: float, destination: str):
        battery_required = distance_km * 0.45  # ప్రతి 1 కిమీ కి 0.45% ఛార్జింగ్ అవసరం
        
        if self.status != "IDLE":
            print(f"⚠️ [{self.vehicle_id}] రైడ్‌కు సిద్ధంగా లేదు! ప్రస్తుత స్థితి: {self.status}")
            return False

        if (self.battery_percentage - battery_required) < AutonomousVehicle.min_battery_threshold:
            print(f"❌ [{self.vehicle_id}] బ్యాటరీ సరిపోదు! అవసరమైనది: {battery_required:.1f}%, ఉన్నది: {self.battery_percentage:.1f}%")
            self.status = "CHARGING"
            return False

        # ట్రిప్ ప్రారంభం
        self.status = "IN_TRANSIT"
        self.battery_percentage -= battery_required
        self.odometer_km += distance_km
        
        trip_entry = {
            "destination": destination,
            "distance_km": distance_km,
            "battery_used": battery_required,
            "timestamp": datetime.datetime.now().strftime("%H:%M:%S")
        }
        self.trip_log.append(trip_entry)
        self.status = "IDLE"
        
        print(f"🚗 [{self.vehicle_id}] '{destination}' ట్రిప్ విజయవంతం! ప్రయాణ దూరం: {distance_km} KM. మిగిలిన బ్యాటరీ: {self.battery_percentage:.1f}%")
        return True

    # 2. ఇన్స్టాన్స్ మెథడ్: రీఛార్జ్ చేయడం
    def recharge(self, target_percentage: float = 100.0):
        print(f"⚡ [{self.vehicle_id}] ఛార్జింగ్ ప్రారంభమైంది... {self.battery_percentage:.1f}% నుండి {target_percentage:.1f}% కి")
        self.battery_percentage = target_percentage
        self.status = "IDLE"
        print(f"🔋 [{self.vehicle_id}] ఛార్జింగ్ పూర్తయింది. రైడ్‌కు సిద్ధం!")

    # 3. క్లాస్ మెథడ్: టెలిమెట్రీ JSON/డిక్షనరీ నుండి ఆబ్జెక్ట్ సృష్టించే ఫ్యాక్టరీ
    @classmethod
    def from_telemetry_dict(cls, data: dict):
        v_id = data.get("vid", "UNKNOWN")
        model = data.get("mod", "Standard EV")
        bat = float(data.get("bat", 100.0))
        return cls(v_id, model, bat)

    # 4. క్లాస్ మెథడ్: మొత్తం ఫ్లీట్ సారాంశ నివేదిక (Fleet Analytics)
    @classmethod
    def print_fleet_summary(cls):
        print("
" + "=" * 65)
        print(f"📊 {cls.fleet_name} — ఎగ్జిక్యూటివ్ ఫ్లీట్ రిపోర్ట్")
        print("=" * 65)
        print(f"మొత్తం యాక్టివ్ వాహనాలు: {len(cls.fleet_registry)}")
        total_kms = sum(v.odometer_km for v in cls.fleet_registry)
        avg_bat = sum(v.battery_percentage for v in cls.fleet_registry) / len(cls.fleet_registry) if cls.fleet_registry else 0.0
        
        print(f"మొత్తం ప్రయాణించిన దూరం: {total_kms:,.2f} KM")
        print(f"సగటు బ్యాటరీ శాతం: {avg_bat:.1f}%")
        print("-" * 65)
        for v in cls.fleet_registry:
            print(f"• ID: {v.vehicle_id:<8} | మోడల్: {v.model:<12} | బాటరీ: {v.battery_percentage:>5.1f}% | ఓడోమీటర్: {v.odometer_km:>6.1f} KM | స్టేటస్: {v.status}")
        print("=" * 65 + "
")

    # 5. స్టాటిక్ మెథడ్: వెహికల్ ID ఫార్మాట్ వాలిడేషన్ (ఉదా: EV-HYD-101)
    @staticmethod
    def validate_id_format(vid: str) -> bool:
        parts = vid.split("-")
        return len(parts) == 3 and parts[0] == "EV" and parts[1].isalpha() and parts[2].isdigit()


# =====================================================================
# సిమ్యులేషన్ మరియు టెస్టింగ్ డ్రైవర్
# =====================================================================
print("🚦 స్మార్ట్ ఆటోనమస్ ఫ్లీట్ సిమ్యులేషన్ ప్రారంభమవుతోంది...")

# ID వాలిడేషన్ పరిశీలన
test_id = "EV-HYD-901"
print(f"వెహికల్ ID '{test_id}' చెల్లుబాటు తనిఖీ: {AutonomousVehicle.validate_id_format(test_id)}")

# వాహనాల ఇన్స్టాన్షియేషన్ (డైరెక్ట్ & ఫ్యాక్టరీ మెథడ్)
v1 = AutonomousVehicle("EV-HYD-101", "Tesla Cyber", battery_percentage=90.0)
v2 = AutonomousVehicle("EV-HYD-102", "Tata Nexon EV", battery_percentage=30.0)
v3 = AutonomousVehicle.from_telemetry_dict({"vid": "EV-BLR-505", "mod": "MG ZS EV", "bat": 95.0})

# రైడ్ ఎగ్జిక్యూషన్లు
v1.execute_trip(25.0, "హైటెక్ సిటీ నుండి రాజీవ్ గాంధీ ఎయిర్‌పోర్ట్")
v2.execute_trip(45.0, "గచ్చిబౌలి నుండి రామంతాపూర్")  # బ్యాటరీ సరిపోక ఫెయిల్ అవుతుంది
v2.recharge(100.0)                                    # రీఛార్జ్ చేశాక మళ్లీ ట్రై చేద్దాం
v2.execute_trip(45.0, "గచ్చిబౌలి నుండి రామంతాపూర్")  # ఇప్పుడు సక్సెస్ అవుతుంది
v3.execute_trip(12.0, "ఎలక్ట్రానిక్ సిటీ కారిడార్")

# ఫ్లీట్ సారాంశ నివేదిక ముద్రణ
AutonomousVehicle.print_fleet_summary()

? మీ అవగాహనను పరీక్షించుకోండి (5 Interactive Quizzes)

1. క్లాస్ (Class) మరియు ఆబ్జెక్ట్ (Object) మధ్య ప్రాథమిక వ్యత్యాసం ఏమిటి?
సమాధానం: క్లాస్ అనేది కేవలం బ్లూప్రింట్ (డిజైన్ లేదా రూల్స్ సెట్) మాత్రమే; ఇది స్వయంగా మెమరీని ఆక్రమించదు. ఆబ్జెక్ట్ (Instance) అనేది ఆ బ్లూప్రింట్ ఆధారంగా ర్యామ్ (RAM) లో మెమరీ కేటాయించబడి సృష్టించబడిన నిజమైన ఎంటిటీ.
2. __init__ మెథడ్ నుండి ఏదైనా వాల్యూను return చేయవచ్చా?
సమాధానం: చేయకూడదు! __init__ మెథడ్ కేవలం None ను మాత్రమే అనుమతిస్తుంది. ఏదైనా ఇతర విలువను (ఉదా: return 10) రిటర్న్ చేయడానికి ప్రయత్నిస్తే పైథాన్ TypeError ను రైజ్ చేస్తుంది.
3. ఇన్స్టాన్స్ మెథడ్స్‌లో self పారామీటర్ మొదటి స్థానంలో ఎందుకు ఉండాలి?
సమాధానం: మీరు obj.method() అని పిలిచినప్పుడు పైథాన్ ఇంటర్‌ప్రీటర్ తెరవెనుక Class.method(obj) గా పిలుస్తుంది. ఆ పిలుపులో మొదటి ఆర్గ్యుమెంట్‌గా వచ్చే కరెంట్ ఆబ్జెక్ట్ రిఫరెన్స్‌ను అందుకోవడానికి self అవసరం.
4. @classmethod మరియు @staticmethod మధ్య ముఖ్యమైన తేడా ఏమిటి?
సమాధానం: @classmethod మొదటి పారామీటర్‌గా క్లాస్ రిఫరెన్స్‌ను (cls) అందుకుంటుంది మరియు ఇది క్లాస్ వేరియబుల్స్‌ను మార్చగలదు లేదా ఆల్టర్నేటివ్ కన్‌స్ట్రక్టర్లను నిర్మించగలదు. కాగా @staticmethod కి self కానీ cls కానీ ఉండవు; ఇది కేవలం స్వతంత్ర యుటిలిటీ ఫంక్షన్ లాగా పనిచేస్తుంది.
5. క్లాస్ స్థాయిలో mutable వేరియబుల్స్ (ఉదా: items = []) డిక్లేర్ చేయడం ఎందుకు ప్రమాదకరం?
సమాధానం: క్లాస్ వేరియబుల్స్ అన్ని ఇన్స్టాన్స్‌లచే పంచుకోబడతాయి (Shared memory). అందువల్ల ఒక ఆబ్జెక్ట్ ఆ లిస్ట్‌ను మార్చినప్పుడు, అన్ని ఇతర ఆబ్జెక్టులలోని లిస్ట్ కూడా మారిపోయి డేటా కాలుష్యం (Data Corruption) ఏర్పడుతుంది.
← మునుపటి అధ్యాయం: 21. ఎక్సెప్షన్ హ్యాండ్లింగ్ తర్వాతి అధ్యాయం: 23. OOP పిల్లర్స్ (Inheritance & Polymorphism) →

ఈ Autonomous Fleet Management Engine ని లైవ్‌గా మన కంపైలర్‌లో రన్ చేయండి!

ఎటువంటి లోకల్ సెటప్ లేకుండా, బ్రౌజర్‌లోనే Modern Python 3 కంపైలర్‌లో ఈ OOP కోడ్‌ను ఎగ్జిక్యూట్ చేసి అవుట్‌పుట్ తనిఖీ చేయండి.