2015-05-21 5 views
5

मैं पायथन (3.4) में कक्षाओं के बारे में पढ़ रहा हूं और जो मुझे लगता है उससे यह लगता है कि हर नई वस्तु के अपने बाध्य तरीकों के उदाहरण हैं।क्या पाइथन वास्तव में हर नए उदाहरण के लिए सभी बाध्य विधि बनाता है?

class A: 

    def __init__(self, name): 
     self.name = name 

    def foo(self): 
     print(self.name) 

a = A('One') 
b = A('Two') 

print(a.foo == b.foo) 

इसका आउटपुट False है।

यह मुझे स्मृति की बर्बादी के रूप में लगता है। मैंने सोचा कि आंतरिक रूप से a.foo और b.foo मेमोरी में किसी भी तरह आंतरिक रूप से इंगित करेगा: A.foo जहां कक्षा उदाहरण के रूप में self पारित किया जाएगा।

मुझे लगता है कि यह शायद भाषा में आसानी से लागू नहीं किया जा सकता है।

क्या प्रत्येक नए उदाहरण में इसके बाध्य तरीकों के नए उदाहरण भी शामिल हैं?

यदि हां, तो क्या यह प्रदर्शन को चोट नहीं पहुंचाता है या अन्य भाषाओं की तुलना में नई वस्तुओं को अधिक सावधानीपूर्वक बनाने के लिए केस बनाता है जहां Java जैसी वस्तुओं के बीच विधियों को "साझा" किया जाता है?

+0

क्या आप जो कुछ पढ़ते हैं उससे लिंक कर सकते हैं जो आपको ऐसा लगता है? –

+0

@SotiriosDelimanolis 'X()। F == X.f' का परिणाम 'गलत' होगा (जहां f एक इंस्ट्रेस विधि है)। यह ऐसा सोचने के लिए पर्याप्त है। –

+0

हालांकि, प्रत्येक बाध्य विधि, समान अंतर्निहित फ़ंक्शन का संदर्भ देती है। रैपर के लिए मेमोरी ओवरहेड न्यूनतम है। – chepner

उत्तर

14

मांग पर मांग पर हैं, प्रत्येक बार जब आप एक तक पहुंचते हैं।

फ़ंक्शन के नाम तक पहुंचने से descriptor protocol पर आक्रमण होता है, जो फ़ंक्शन ऑब्जेक्ट्स पर बाध्य विधि देता है।

एक बाध्य विधि फ़ंक्शन ऑब्जेक्ट के चारों ओर एक पतली आवरण है; यह मूल कार्य और उदाहरण के लिए एक संदर्भ संग्रहीत करता है। विधि ऑब्जेक्ट को कॉल करते समय, यह बदले में कॉल को फ़ंक्शन पर पास करता है, उदाहरण के साथ पहले तर्क के रूप में डाला जाता है।

उदाहरण बनाये जाने पर विधियां नहीं बनाई गई हैं, इसलिए कोई अतिरिक्त स्मृति आवश्यक नहीं है।

आप चरणों मैन्युअल रूप से पुनः बना सकते हैं:

>>> class A: 
...  def __init__(self, name): 
...   self.name = name 
...  def foo(self): 
...   print(self.name) 
... 
>>> a = A('One') 
>>> a.foo 
<bound method A.foo of <__main__.A object at 0x100a27978>> 
>>> a.foo.__self__ 
<__main__.A object at 0x100a27978> 
>>> a.foo.__func__ 
<function A.foo at 0x100a22598> 
>>> A.__dict__['foo'] 
<function A.foo at 0x100a22598> 
>>> A.__dict__['foo'].__get__(a, A) 
<bound method A.foo of <__main__.A object at 0x100a27978>> 
>>> A.__dict__['foo'].__get__(a, A)() 
One 

यह केवल विधि उद्देश्य यह है कि हर बार निर्मित किया जाता है; अंतर्निहित समारोह स्थिर बनी हुई है:

>>> a.foo is a.foo 
False 
>>> b = A('Two') 
>>> b.foo is a.foo 
False 
>>> b.foo.__func__ is a.foo.__func__ 
True 

यह वास्तुकला भी बनाता है classmethod, staticmethod, और property वस्तुओं काम करते हैं। आप दिलचस्प बाध्यकारी व्यवहारों का एक पूरा मेजबान बनाकर, अपने स्वयं के वर्णनकर्ता बना सकते हैं।

+0

यह आपका उत्तर भी है, इसलिए आपको प्रतिनिधि को स्पष्ट रूप से किसी भी तरह की आवश्यकता नहीं है; o) – jonrsharpe

+0

@jonrsharpe: हाँ, लेकिन यह पहले से ही स्वीकार कर लिया गया है! :- पी मैंने इस सवाल को पूरी तरह से फिर से पढ़ा नहीं है; पूर्वदर्शी में प्रश्न और उत्तर दोनों एक सही डुप्लिकेट हैं। मुझे लगता था कि दूसरी पोस्ट पर व्याख्या करने के लिए और कुछ था। –

संबंधित मुद्दे