22. ఆబ్జెక్ట్ ఓరియెంటెడ్ ప్రోగ్రామింగ్ (OOP) బేసిక్స్ — Classes, Objects, __init__ & self
__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):
- క్లాస్ నేమ్స్పేస్: క్లాస్ డిక్లేర్ అయిన వెంటనే పైథాన్ దానికి ఒక ప్రత్యేకమైన నేమ్స్పేస్ డిక్షనరీని (
ClassName.__dict__) సృష్టిస్తుంది. - ఇన్స్టాన్షియేషన్ (Instantiation): క్లాస్ పేరు పక్కన బ్రాకెట్లను ఉంచి పిలిచినప్పుడు (ఉదా:
c = Car()), పైథాన్ రన్టైమ్ ఆ క్లాస్ ఆధారంగా RAM లో కొత్త మెమరీ స్పేస్ను కేటాయించి కొత్త ఆబ్జెక్ట్ను అందిస్తుంది. - ఆబ్జెక్ట్ ఐడెంటిటీ:
id(obj1)మరియుid(obj2)లను తనిఖీ చేస్తే, ఒకే క్లాస్ నుండి పుట్టినప్పటికీ ప్రతి ఆబ్జెక్ట్ సంపూర్ణంగా విభిన్నమైన మెమరీ లొకేషన్ను కలిగి ఉంటుందని స్పష్టంగా గమనించవచ్చు.
4 __init__ మెథడ్ డీప్ డైవ్ (Constructor Lifecycle & __new__)
ఆబ్జెక్ట్ సృష్టించబడిన వెంటనే దానికి అవసరమైన ప్రారంభ విలువలను (Initial State) కేటాయించడానికి పైథాన్లో ప్రత్యేకమైన డండర్ (Double Underscore) మెథడ్ __init__ ను వాడతాము. దీనిని సాంప్రదాయ ప్రోగ్రామింగ్లో Constructor అని పిలుస్తారు:
ఆబ్జెక్ట్ సృష్టి ప్రయాణం: __new__ vs __init__ అంతర్గత రహస్యం:
చాలామంది __init__ ఆబ్జెక్ట్ను సృష్టిస్తుందని అనుకుంటారు. కానీ వాస్తవానికి పైథాన్ అంతర్గతంగా రెండు వేర్వేరు దశలను నిర్వహిస్తుంది:
- దశ 1:
__new__(cls, ...)(ది క్రియేటర్): ఇది స్టాటిక్ మెథడ్. ఇది ఆపరేటింగ్ సిస్టమ్ నుండి కొత్త మెమరీ బ్లాక్ను కేటాయించి, ఒక ఖాళీ "రా ఆబ్జెక్ట్" (Uninitialized Instance) ను సృష్టించి రిటర్న్ చేస్తుంది. Singleton Design Pattern వంటి ఆర్కిటెక్చర్లలో ఆబ్జెక్ట్ సృష్టిని నియంత్రించడానికి దీనిని ఓవర్రైడ్ చేస్తారు. - దశ 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__ లో నిల్వ ఉంటుంది |
__slots__: పైథాన్లో ప్రతి సాధారణ ఆబ్జెక్ట్ డైనమిక్ అట్రిబ్యూట్ల కోసం లోపల ఒక డిక్షనరీని (__dict__) నిర్వహిస్తుంది. దీనివల్ల వేల కొద్దీ ఆబ్జెక్టులు ఉన్నప్పుడు భారీగా RAM వృథా అవుతుంది. మీరు క్లాస్లో __slots__ = ('name', 'salary') అని డిఫైన్ చేస్తే, పైథాన్ __dict__ ను తొలగించి స్థిరమైన C-స్ట్రక్చర్ శైలిలో మెమరీని కేటాయిస్తుంది. దీనివల్ల మెమరీ వినియోగం దాదాపు 40% నుండి 50% వరకు తగ్గుతుంది!
7 ఇన్స్టాన్స్ మెథడ్స్ (Instance Methods)
క్లాస్లో డిఫాల్ట్గా రాసే మెథడ్స్ అన్నీ ఇన్స్టాన్స్ మెథడ్లే. వీటి మొదటి పారామీటర్ ఎల్లప్పుడూ self. ఇవి నిర్దిష్ట ఆబ్జెక్ట్ యొక్క స్టేట్ను చదవగలవు, విలువలను మార్చగలవు, అలాగే ఇతర ఇన్స్టాన్స్ మెథడ్లను పిలవగలవు. ఉదాహరణకు ఒక బ్యాంకింగ్ అకౌంట్లో డిపాజిట్ చేయడం లేదా విత్డ్రా చేయడం వంటి చర్యలు ఆ నిర్దిష్ట వ్యక్తి బ్యాలెన్స్ను మాత్రమే మార్చాలి కాబట్టి అవి ఇన్స్టాన్స్ మెథడ్స్గా రూపొందించబడతాయి.
8 క్లాస్ మెథడ్స్ (@classmethod & cls పారామీటర్)
కొన్ని సందర్భాలలో మనకు ఒక నిర్దిష్ట ఆబ్జెక్ట్ డేటాతో పని ఉండదు; బదులుగా మొత్తం క్లాస్ వేరియబుల్స్ను మార్చాల్సి ఉంటుంది లేదా Alternative Constructors (వివిధ ఫార్మాట్ల డేటా నుండి ఆబ్జెక్టులను సృష్టించే ఫ్యాక్టరీ మెథడ్స్) నిర్మించాల్సి ఉంటుంది. దీని కోసం @classmethod డెకరేటర్ను మరియు మొదటి పారామీటర్గా cls (క్లాస్ రెఫరెన్స్) ను ఉపయోగిస్తాము:
- ఫ్యాక్టరీ కన్స్ట్రక్టర్లు: డేటాబేస్ JSON డిక్షనరీ నుండి (
from_dict), లేదా CSV లైన్ నుండి (from_csv), లేదా వెబ్ రిక్వెస్ట్ నుండి నేరుగా ఆబ్జెక్ట్ను ఇన్స్టాన్షియేట్ చేయడానికి క్లాస్ మెథడ్స్ అద్భుతంగా తోడ్పడతాయి. - సబ్క్లాసింగ్ సేఫ్టీ:
cls(...)అని పిలవడం వల్ల, భవిష్యత్తులో ఈ క్లాస్ను ఇన్హెరిట్ చేసుకున్న చైల్డ్ క్లాస్ నుండి పిలిచినా సరైన చైల్డ్ క్లాస్ ఆబ్జెక్టే సృష్టించబడుతుంది!
9 స్టాటిక్ మెథడ్స్ (@staticmethod) & మెథడ్స్ త్రయం సమగ్ర పోలిక
ఒక మెథడ్కు ఆబ్జెక్ట్ డేటాతో (self) పని లేదు, మరియు క్లాస్ వేరియబుల్స్తో (cls) కూడా పని లేదు; కానీ లాజికల్గా ఆ క్లాస్కు సంబంధించిన యుటిలిటీ లేదా వాలిడేషన్ ఫంక్షన్ అయితే, దానిని @staticmethod గా డిక్లేర్ చేస్తాము:
| లక్షణం | Instance Method | Class Method (@classmethod) | Static Method (@staticmethod) |
|---|---|---|---|
| మొదటి పారామీటర్ | self (ఆబ్జెక్ట్ రెఫరెన్స్) |
cls (క్లాస్ రెఫరెన్స్) |
ఏదీ లేదు (సాధారణ పారామీటర్లు మాత్రమే) |
| స్టేట్ మోడిఫికేషన్ | ఆబ్జెక్ట్ స్టేట్ను మార్చగలదు | క్లాస్ స్టేట్ను మార్చగలదు | ఆబ్జెక్ట్ లేదా క్లాస్ స్టేట్ను మార్చలేదు |
| వాడాల్సిన ప్రధాన సందర్భం | బిజినెస్ బిహేవియర్ & డేటా ఆపరేషన్లు | ఫ్యాక్టరీ మెథడ్స్, ఆల్టర్నేటివ్ కన్స్ట్రక్టర్లు | వాలిడేషన్, యుటిలిటీ గణనలు, హెల్పర్ లాజిక్ |
10 కోడ్ డెమో 1: బ్యాంకింగ్ అకౌంట్ మోడలింగ్ (Complete Implementation)
డిపాజిట్, విత్డ్రా, మరియు బ్యాలెన్స్ ఎంక్వైరీతో కూడిన పూర్తి బ్యాంకింగ్ అకౌంట్ క్లాస్ను లైవ్గా పరిశీలిద్దాం:
# చాప్టర్ 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
క్లాస్ మెథడ్స్ మరియు స్టాటిక్ మెథడ్స్ రియల్-వరల్డ్ సాఫ్ట్వేర్లో డేటా పార్సింగ్ మరియు బిజినెస్ రూల్స్కు ఎలా ఉపయోగపడతాయో చూద్దాం:
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 కామన్ బిగినర్స్ మిస్టేక్స్ & ప్రొడక్షన్ బెస్ట్ ప్రాక్టీసెస్
- Mutable Class Attribute Trap: క్లాస్ స్థాయిలో లిస్ట్ లేదా డిక్షనరీ వంటి మ్యూటబుల్ వస్తువును డిక్లేర్ చేస్తే (ఉదా:
items = []), ప్రతి ఆబ్జెక్ట్ అదే లిస్ట్ను షేర్ చేసుకుంటుంది! ఒక కస్టమర్ కార్ట్లోకి వస్తువును చేరిస్తే అందరి కార్టులలోకి అది కనిపిస్తుంది. ఎల్లప్పుడూ మ్యూటబుల్ డేటాను__init__లోself.items = []గానే డిక్లేర్ చేయాలి. - self మర్చిపోవడం: మెథడ్ డిఫైన్ చేసేటప్పుడు మొదటి ఆర్గ్యుమెంట్గా
selfరాయడం మర్చిపోతే, కాల్ చేసినప్పుడుTypeError: takes 0 positional arguments but 1 was givenఎర్రర్ వస్తుంది. - Instance Variable vs Class Variable Shadowing: క్లాస్ వేరియబుల్ను ఆబ్జెక్ట్ ద్వారా మోడిఫై చేయడానికి ప్రయత్నిస్తే (
self.company_name = "NewName"), అది క్లాస్ వేరియబుల్ను మార్చదు; బదులుగా ఆ ఆబ్జెక్ట్కు మాత్రమే వర్తించే ఒక కొత్త ఇన్స్టాన్స్ వేరియబుల్ను సృష్టిస్తుంది (Shadowing). క్లాస్ వేరియబుల్ను మార్చాలంటే నేరుగాClassName.variable = valueఅని రాయాలి. - OOP ని అవసరం లేని చోట బలవంతంగా రుద్దకండి: కేవలం రెండు సాధారణ మ్యాథమెటికల్ కాలిక్యులేషన్ల కోసం భారీ క్లాసులను నిర్మించకూడదు. స్టేట్ (State) మరియు బిహేవియర్ (Behavior) కలగలసినప్పుడే OOP ఉపయోగించాలి.
13 రియల్-వరల్డ్ ప్రాజెక్ట్: "Smart Autonomous Vehicle Fleet Management Engine"
ఈ అధ్యాయంలో నేర్చుకున్న క్లాసెస్, ఆబ్జెక్ట్స్, __init__ కన్స్ట్రక్టర్, క్లాస్ అట్రిబ్యూట్స్, ఇన్స్టాన్స్ మెథడ్స్, @classmethod మరియు @staticmethod లన్నింటినీ రంగరించి — ఒక పూర్తి స్థాయి Smart Autonomous Vehicle Fleet Management System ను నిర్మిద్దాం! ఈ ఇంజిన్ వాహనాల బ్యాటరీ స్థితి, ప్రయాణ కిలోమీటర్లు, సర్వీసింగ్ అలర్టులు మరియు ఫ్లీట్ సారాంశ విశ్లేషణలను సమగ్రంగా నిర్వహిస్తుంది.
# =====================================================================
# చాప్టర్ 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) మధ్య ప్రాథమిక వ్యత్యాసం ఏమిటి?
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 = []) డిక్లేర్ చేయడం ఎందుకు ప్రమాదకరం?
ఈ Autonomous Fleet Management Engine ని లైవ్గా మన కంపైలర్లో రన్ చేయండి!
ఎటువంటి లోకల్ సెటప్ లేకుండా, బ్రౌజర్లోనే Modern Python 3 కంపైలర్లో ఈ OOP కోడ్ను ఎగ్జిక్యూట్ చేసి అవుట్పుట్ తనిఖీ చేయండి.