ठीक है, पहले चीजें पहले।
पायथन में "वैरिएबल डिक्लेरेशन" या "वैरिएबल इनिशियलाइजेशन" जैसी कोई चीज नहीं है।
वहाँ बस है जिसे हम "असाइनमेंट" कहते हैं, लेकिन शायद सिर्फ "नामकरण" कहा जाना चाहिए।
असाइनमेंट का अर्थ है "बाएं हाथ की तरफ का यह नाम अब दाहिने हाथ की ओर के मूल्यांकन के परिणाम को संदर्भित करता है, भले ही यह पहले (अगर कुछ भी) संदर्भित किया गया हो"।
foo = 'bar'
foo = 2 * 3
जैसे, पायथन के नाम ("चर" से बेहतर शब्द, यकीनन) संबद्ध प्रकार नहीं हैं; मान करते हैं। आप इसके प्रकार की परवाह किए बिना किसी भी नाम को फिर से लागू कर सकते हैं, लेकिन उस चीज का व्यवहार अभी भी है जो उसके प्रकार पर निर्भर है। नाम केवल मूल्य (वस्तु) को संदर्भित करने का एक तरीका है। यह आपके दूसरे प्रश्न का उत्तर देता है: आप कस्टम प्रकार रखने के लिए चर नहीं बनाते हैं। आप किसी विशेष प्रकार को धारण करने के लिए चर नहीं बनाते हैं। आप चर बिल्कुल भी नहीं बनाते हैं। आप वस्तुओं को नाम देते हैं।
दूसरा बिंदु: कक्षाओं में आने पर पायथन एक बहुत ही सरल नियम का पालन करता है, जो कि वास्तव में जावा, सी ++ और सी # जैसी भाषाओं की तुलना में बहुत अधिक सुसंगत है: ब्लॉक के अंदर घोषित सब कुछ class
कक्षा का हिस्सा है । इसलिए, def
यहां लिखे गए कार्य ( ) तरीके हैं, अर्थात कक्षा ऑब्जेक्ट का हिस्सा (प्रति-उदाहरण के आधार पर संग्रहीत नहीं), जैसे जावा, सी ++ और सी # में; लेकिन यहाँ अन्य नाम भी कक्षा का हिस्सा हैं । फिर, नाम सिर्फ नाम हैं, और उनके पास संबद्ध प्रकार नहीं हैं, और फ़ंक्शन भी पायथन में ऑब्जेक्ट हैं। इस प्रकार:
class Example:
data = 42
def method(self): pass
कक्षाएं पिथॉन में भी ऑब्जेक्ट हैं ।
तो अब हमने एक ऑब्जेक्ट बनाया है जिसका नाम है Example
, जो उन सभी चीजों के वर्ग का प्रतिनिधित्व करता है जो Example
एस हैं। इस ऑब्जेक्ट में दो उपयोगकर्ता-प्रदत्त विशेषताएँ हैं (C C ++ में, "सदस्य"; C # में, "फ़ील्ड या गुण या विधियाँ"; जावा में, "फ़ील्ड या विधियाँ")। उनमें से एक का नाम है data
, और यह पूर्णांक मान संग्रहीत करता है 42
। दूसरे का नाम है method
, और यह एक फ़ंक्शन ऑब्जेक्ट संग्रहीत करता है। (कई और विशेषताएँ हैं जिन्हें पायथन अपने आप जोड़ता है।)
ये विशेषताएँ अभी भी वास्तव में वस्तु का हिस्सा नहीं हैं, हालाँकि। मौलिक रूप से, एक वस्तु सिर्फ और अधिक नामों (विशेषता नामों) का एक बंडल है, जब तक आप उन चीजों के लिए नीचे नहीं आते हैं जिन्हें किसी भी अधिक विभाजित नहीं किया जा सकता है। इस प्रकार, मानों को एक वर्ग के विभिन्न उदाहरणों के बीच, या यहां तक कि विभिन्न वर्गों की वस्तुओं के बीच साझा किया जा सकता है, यदि आप जानबूझकर इसे सेट करते हैं।
आइए एक उदाहरण बनाएं:
x = Example()
अब हमारे पास नाम की एक अलग वस्तु है x
, जिसका एक उदाहरण है Example
। data
और method
वास्तव में वस्तु का हिस्सा नहीं हैं, लेकिन हम अभी भी के माध्यम से उन्हें देख सकते हैं x
कुछ जादू अजगर पर्दे के पीछे है कि की वजह से। जब हम ऊपर देखते हैं method
, विशेष रूप से, हम इसके बजाय एक "बाध्य विधि" प्राप्त करेंगे (जब हम इसे कहते हैं, x
तो self
पैरामीटर के रूप में स्वचालित रूप से पारित हो जाता है , जो कि Example.method
सीधे ऊपर देखने पर ऐसा नहीं हो सकता है )।
जब हम उपयोग करने की कोशिश करते हैं तो क्या होता है x.data
?
जब हम इसकी जांच करते हैं, तो यह पहले ऑब्जेक्ट में दिखाई देता है। यदि यह ऑब्जेक्ट में नहीं पाया जाता है, तो पायथन क्लास में दिखता है।
हालाँकि, जब हम असाइन करते हैं x.data
, तो पायथन ऑब्जेक्ट पर एक विशेषता बनाएगा। यह वर्ग की विशेषता को प्रतिस्थापित नहीं करेगा ।
यह हमें ऑब्जेक्ट इनिशियलाइज़ेशन करने की अनुमति देता है । पायथन स्वचालित रूप से __init__
नए इंस्टेंस पर कक्षा की विधि को कॉल करेगा जब वे बनाए जाते हैं, यदि मौजूद हो। इस विधि में, हम प्रत्येक वस्तु पर उस विशेषता के लिए प्रारंभिक मान सेट करने के लिए विशेषताओं को निर्दिष्ट कर सकते हैं:
class Example:
name = "Ignored"
def __init__(self, name):
self.name = name
अब हमें निर्दिष्ट करना चाहिए name
जब हम एक बनाते हैं Example
, और प्रत्येक उदाहरण का अपना होता है name
। Example.name
जब भी हम .name
किसी उदाहरण को देखते हैं तो पायथन वर्ग की विशेषता को अनदेखा कर देगा , क्योंकि उदाहरण की विशेषता पहले मिल जाएगी।
एक अंतिम चेतावनी: संशोधन (उत्परिवर्तन) और असाइनमेंट अलग-अलग चीजें हैं!
पायथन में, तार अपरिवर्तनीय हैं। उन्हें संशोधित नहीं किया जा सकता है। जब तुम करोगे:
a = 'hi '
b = a
a += 'mom'
आप मूल 'हाय' स्ट्रिंग को नहीं बदलते हैं । पायथन में यह असंभव है। इसके बजाय, आप एक नया स्ट्रिंग बनाते हैं 'hi mom'
, और इसके a
लिए एक नाम होना बंद करने का कारण बनते हैं 'hi '
, और 'hi mom'
इसके बजाय एक नाम होना शुरू करते हैं। हमने b
एक नाम भी बनाया है 'hi '
, और नाम को फिर से लागू करने के बाद a
, b
अभी भी एक नाम है 'hi '
, क्योंकि 'hi '
अभी भी मौजूद है और इसे बदला नहीं गया है।
लेकिन सूचियों को बदला जा सकता है:
a = [1, 2, 3]
b = a
a += [4]
अब b
[1, 2, 3, 4] भी है, क्योंकि हमने b
एक ही चीज़ के लिए एक नाम बनाया है a
, और फिर हमने उस चीज़ को बदल दिया। हमने a
नाम के लिए एक नई सूची नहीं बनाई है , क्योंकि पायथन बस +=
सूचियों के लिए अलग तरह से व्यवहार करता है।
यह वस्तुओं के लिए मायने रखता है क्योंकि यदि आपके पास एक वर्ग विशेषता के रूप में एक सूची थी, और सूची को संशोधित करने के लिए एक उदाहरण का उपयोग किया था, तो अन्य सभी उदाहरणों में परिवर्तन "देखा" होगा। ऐसा इसलिए है क्योंकि (ए) डेटा वास्तव में क्लास ऑब्जेक्ट का हिस्सा है, न कि किसी इंस्टेंस ऑब्जेक्ट का; (b) क्योंकि आप सूची को संशोधित कर रहे थे और एक साधारण असाइनमेंट नहीं कर रहे थे, इसलिए आपने क्लास की विशेषता को छिपाते हुए एक नया उदाहरण विशेषता नहीं बनाया।