अच्छी तरह डिज़ाइन की गई क्लास से अपने कोड को व्यवस्थित करें: इनिशियलाइज़ेशन, इंस्टेंस या क्लास एट्रिब्यूट, इनहेरिटेंस और उसके समझौते।
इस पाठ को Kodokon में खोलेंआप हर समय Python के ऑब्जेक्ट के साथ काम करते हैं: स्ट्रिंग, लिस्ट, फ़ाइलें। अपनी खुद की क्लास लिखने का मतलब है स्टेट (एट्रिब्यूट) और व्यवहार (मेथड) को एक सुसंगत इंटरफ़ेस के पीछे एक साथ बाँध देना। शब्दावली का एक ऐसा बिंदु जिसे अक्सर गलत समझा जाता है: __init__ कोई कंस्ट्रक्टर नहीं है। जब __init__ को self मिलता है, तब तक ऑब्जेक्ट पहले से मौजूद होता है (__new__ द्वारा बनाया गया); इसका काम इंस्टेंस को इनिशियलाइज़ करना है। और self में कुछ भी जादुई नहीं है: यह हर इंस्टेंस मेथड का पहला पैरामीटर है, जिसे Python कॉल के समय अपने आप पास कर देता है।
class Account:
def __init__(self, owner, balance=0.0):
self.owner = owner
self.balance = balance
def deposit(self, amount):
if amount <= 0:
raise ValueError("amount must be > 0")
self.balance += amount
return self.balance
def __repr__(self):
return f"Account({self.owner!r}, {self.balance})"
account = Account("Ada")
account.deposit(120.0)
print(account)प्रोडक्शन में एक निर्णायक भेद: क्लास एट्रिब्यूट क्लास के मुख्य भाग में घोषित होते हैं और हर इंस्टेंस द्वारा साझा किए जाते हैं; इंस्टेंस एट्रिब्यूट self पर बनाए जाते हैं, आमतौर पर __init__ में। पढ़ते समय, Python पहले इंस्टेंस पर देखता है, फिर क्लास पर, फिर पैरेंट क्लास पर। असाइनमेंट self.x = ... हमेशा एक इंस्टेंस एट्रिब्यूट बनाता है, जो उसी नाम वाले क्लास एट्रिब्यूट को ढक देता है। वास्तविक दुनिया का क्लासिक जाल: एक म्यूटेबल क्लास एट्रिब्यूट।
class Basket:
items = []
def add(self, item):
self.items.append(item)
a = Basket()
b = Basket()
a.add("apple")
print(b.items) # ['apple']: shared list!इनहेरिटेंस एक "is a" (है एक) संबंध व्यक्त करता है: एक Car है एक Vehicle। सबक्लास मेथड इनहेरिट करती है, उन्हें ओवरराइड कर सकती है, और super() उसे पैरेंट वाला संस्करण कॉल करने देता है - __init__ में यह अनिवार्य है, ताकि आप पैरेंट का इनिशियलाइज़ेशन शॉर्ट-सर्किट न कर दें। Python MRO (Method Resolution Order) का अनुसरण करते हुए कॉल का समाधान करता है। हर बार इनहेरिटेंस की ओर मत भागिए: "is a" संबंध के बिना कोड का पुनः उपयोग करने के लिए, कंपोज़िशन को प्राथमिकता दें (एक ऑब्जेक्ट दूसरे का स्वामी होता है)। गहरी पदानुक्रम नाज़ुक होती हैं: हर पैरेंट क्लास अपनी सभी संतानों के लिए एक अंतर्निहित API बन जाती है।
class Vehicle:
def __init__(self, brand):
self.brand = brand
def describe(self):
return self.brand
class Car(Vehicle):
def __init__(self, brand, doors):
super().__init__(brand)
self.doors = doors
def describe(self):
base = super().describe()
return f"{base}, {self.doors} doors"
print(Car("Aster", 5).describe())