2011-02-25 15 views
8

सामान्य ओओपी का उपयोग करने के बजाय, जावा और सी # जैसे उनके बेस क्लास Object या object के साथ करते हैं, पायथन वस्तुओं के मूल व्यवहार के लिए विशेष तरीकों का उपयोग करता है। अजगर का उपयोग करता __str__ जो जब वस्तु print में भेजा जाता है प्रयोग किया जाता है:पायथन में असामान्य ओओपी का कारण?

>>> class Demo: 
>>> def __str__(self): 
>>>  return "representation" 

>>> d = Demo() 
>>> print(d) 
representation 

ही len साथ:

>>> class Ruler: 
>>> def __len__(self): 
>>>  return 42 

>>> r = Ruler() 
>>> len(r) 
42 

मैं क्या उम्मीद करेंगे कुछ इस तरह है:

>>> class Ruler: 
>>> def len(self): 
>>>  return 42 

>>> r = Ruler() 
>>> r.len() 
42 

क्या सामान्य तरीकों को सीधे कॉल करने के बजाय अप्रत्यक्ष रूप से विशेष तरीकों का उपयोग करने का कारण क्या है?

+2

के रूप में \ _ \ _ str \ _ \ _, मैं यह समझ के रूप में, यह जावा/सी # के toString के बराबर है। \ _ \ _ str \ _ \ _ ऑब्जेक्ट का एक टेक्स्ट प्रस्तुतिकरण देता है, जो प्रिंट से स्पष्ट रूप से अलग है - मानक आउटपुट में पाठ का प्रतिनिधित्व प्रिंट करें। – ChrisJ

+4

क्या यह आपका मतलब है? http://docs.python.org/faq/design.html#why-does-python-use-methods-for-some-functionality-eg-list-index-but-functions-for-other-eg-len- सूची –

+0

@ थॉमस हां, यही जवाब है। शायद आप इसे एक उत्तर के रूप में लिखना चाहते हैं ... – deamon

उत्तर

13

इस का कारण यह अजगर प्रलेखन यहाँ में अच्छी तरह से समझाया गया है:

http://docs.python.org/faq/design.html#why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list

प्रमुख कारण इतिहास है। कार्य उन कार्यों कि प्रकार और के एक समूह जो भी के लिए वस्तुओं कि सभी (जैसे tuples) पर तरीकों नहीं था काम करने का इरादा कर रहे थे के लिए सामान्य थे के लिए इस्तेमाल किया गया। यह भी एक ऐसा फ़ंक्शन रखने के लिए सुविधाजनक है जो आसानी से अस्थिर ऑब्जेक्ट्स संग्रह पर लागू हो सकता है जब आप पायथन (मानचित्र(), लागू() et al) की कार्यात्मक विशेषताओं का उपयोग करते हैं।

वास्तव में, लेन (लागू करने), अधिकतम(), मिनट() एक अंतर्निहित समारोह के रूप में उन्हें प्रत्येक प्रकार के लिए तरीके के रूप में लागू करने की तुलना में वास्तव में कम कोड है। कोई व्यक्ति व्यक्तिगत मामलों के बारे में चिंतन कर सकता है लेकिन यह पायथन का हिस्सा है, और यह भी इस तरह के मौलिक परिवर्तन बनाने के लिए देर हो चुकी है। बड़े पैमाने पर कोड ब्रेकेज से बचने के लिए कार्यों को पर रहना होगा।

(इस टिप्पणी में जवाब दिया गया था, लेकिन भविष्य पाठकों के लिए एक असली जवाब के रूप में दिखाया जा सकता है की जरूरत है।)

+2

आपने मुझे इसे हरा दिया ;-) –

+1

एक और [अच्छा तर्क] (http://lucumr.pocoo.org/2011/7/9/python-and-pola/) यह है कि 'लेन' जैसे कार्य एक अग्रणी हैं अधिक सुसंगत एपीआई। – deamon

4

ये हुक नहीं हैं।

वे विशेष नामों के साथ बस तरीके हैं।

पायथन में विशेष विधि नामों के लिए सम्मेलन __name__ है।

बिल्ट-इन लेन, इटर, स्ट्र, रिप्र (और अन्य) फ़ंक्शंस सामान्य विधियों का उपयोग उन नामों के साथ करते हैं जो एक विशेष सम्मेलन का पालन करते हैं ताकि हम सभी सुनिश्चित हो सकें कि हमने विशेष तरीकों को सही तरीके से कार्यान्वित किया है।

विशेष तरीकों के अजीब दिखने वाले नाम हैं ताकि हम किसी भी नाम का उपयोग करने के लिए स्वतंत्र हों, जिसे हम टकराव के डर के बिना चाहते हैं।


obj.len() और अधिक सहज ज्ञान युक्त हो, लागू करने और उपयोग करने के लिए होगा।

शायद आप के लिए। दूसरों के लिए, यह पूरी तरह से परेशान हो सकता है।

पायथन में दोनों कई सामान्य कार्यों के लिए विधि नोटेशन और फ़ंक्शन नोटेशन है।

और फ़ंक्शन नोटेशन को प्राथमिकता दी जाती है।

यह अभी भी ओओ प्रोग्रामिंग है। केवल नोटेशन बदल दिया गया है।

+0

ठीक है, चलिए इसे "विशेष तरीकों" कहते हैं। '__len__' को केवल अप्रत्यक्ष रूप से क्यों कहा जाता है? obj.len() लागू करने और उपयोग करने के लिए और अधिक सहज ज्ञान युक्त होगा। – deamon

+0

यह उनके प्रश्न के दिल में नहीं मिलता है। – FogleBird

+0

@FogleBird: मुझे खुशी है कि आप प्रश्न के दिल को समझ गए हैं। जाहिर है, मैं इसे समझ नहीं सका। –

0

हुक मानक फ़ंक्शंस के व्यवहार को फिर से परिभाषित करने की अनुमति देते हैं। __add__() ओवरराइड करने पर विचार करें और मानक infix + ऑपरेटर बनाम कस्टम add() और नेस्टेड कॉल का उपयोग करके देखें।

इसके अलावा, यदि आप __iter__() परिभाषित करते हैं, तो आप अपने ऑब्जेक्ट को for ... in लूप में उपयोग कर सकते हैं। एक लूप को नियंत्रित करने और हाथ से पुनरावृत्ति को आगे बढ़ाने के लिए इसकी तुलना करें। __call__() ओवरराइड करने पर विचार करें और अपने उदाहरणों को किसी भी अन्य कार्य के रूप में अच्छे कार्यों में बदल दें। यह भारी लचीलापन देता है।

यदि आप चाहते हैं, तो जावा .toString() के साथ ऐसा ही करता है जो ऑब्जेक्ट प्रिंट करते समय या स्ट्रिंग में इसे संयोजित करते समय पूरी तरह से काम करता है।

0

कोई पाइथोनिस्टा नहीं है, इसलिए यह रास्ता बंद हो सकता है, लेकिन अगर मैं आपका प्रश्न समझता हूं, तो मेरी धारणा यह है कि यह व्यवहार की बजाय शैली और मुहावरे का मामला है।जावा, और कुछ हद तक सी #, बहुत verbose, canonical और ऑर्थोगोनल भाषाओं हैं। सबकुछ एक वस्तु है (या सी #, के लिए व्यवहार करता है जैसे एक - आईआईआरसी int.toString() मान्य है), और आपके प्रोग्राम को जो भी कुछ भी स्पष्ट रूप से व्यक्त किया जाना चाहिए।

पायथन अधिक स्पष्टता है, जो स्पष्टता के कभी-कभी खर्च पर सुविधा का मूल्यांकन करता है। आप इसे सी ++ में भी देखेंगे, निहित रूपांतरण और ऑपरेटिंग ओवरलोडिंग के साथ। बस अपने toString() उदाहरण के लिए सी ++ अनुरूप पर विचार करें:

std::ostream& operator<<(std::ostream& outstream, const Widget& rhs) 
{ 
    return outstream << rhs.name(); 
} 

std::cout << myWidget; 
+0

मुझे लगता है कि आपको इसके बारे में एक बिंदु मिल गया है - पायथन का उद्देश्य स्पष्ट और कॉम्पैक्ट के बीच संतुलन का लक्ष्य है। लेकिन पायथन में, सब कुछ 'ऑब्जेक्ट' से प्राप्त होता है, और यदि आप चाहते हैं तो आप 'someint .__ str __() 'कर सकते हैं (यह पुनः संयोजित नहीं है, लेकिन यह' str (someint)' जैसा ही है)। –

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