2008-09-17 12 views
18

उदाहरण:क्यों 'लेन' अजगर में शब्दकोशों और सूचियों को विरासत में कार्य नहीं है

a_list = [1, 2, 3] 
a_list.len() # doesn't work 
len(a_list) # works 

अजगर जा रहा है (बहुत) वस्तु उन्मुख, मुझे समझ नहीं आता क्यों 'लेन' कार्य नहीं है वस्तु द्वारा विरासत में मिला। प्लस मैं गलत समाधान की कोशिश करता रहता हूं क्योंकि यह मेरे लिए तार्किक रूप में दिखाई देता है

+0

कार्य नहीं ली गई है। तरीके हैं आप किस ऑब्जेक्ट की 'लेन' विधि से उत्तराधिकारी बनना चाहेंगे? – tzot

+0

यह अप्रासंगिक है क्योंकि लेन सिर्फ __len__ विधि को कॉल करता है, इसलिए वही विरासत समस्याएं अभी भी लागू होंगी। –

+5

@Eli आपका मतलब '__len__' विधि है - इसलिए बोल्ड के रूप में डबल अंडरस्कोर का अर्थ है। =) – MatrixFrog

उत्तर

40

गुइडो की व्याख्या here है:

सभी की

पहले, मैं लेन चुना x.len() एचसीआई कारणों के लिए अधिक (एक्स) (डीईएफ़ __len __() बाद में ज्यादा आया)। वास्तव में दो इंटरविवाइड कारण हैं, एचसीआई:

(ए) कुछ परिचालनों के लिए, उपसर्ग नोटेशन सिर्फ पोस्टफिक्स से बेहतर पढ़ता है - उपसर्ग (और infix!) संचालन गणित में एक लंबी परंपरा है जो टिप्पणियों को पसंद करता है जहां दृश्य मदद करते हैं गणितज्ञ एक समस्या के बारे में सोच रहा है। कच्चे ओओ नोटेशन का उपयोग करके एक ही चीज करने की चतुरता के लिए हम आसानी से तुलना करें जैसे x * (ए + बी) x ए + x बी में एक सूत्र को फिर से लिखना।

(बी) जब मैं लैन (x) कहता हूं कि कोड पढ़ता है तो मुझे पता है कि यह कुछ की लंबाई मांग रहा है। यह मुझे दो चीजें बताता है: परिणाम एक पूर्णांक है, और तर्क किसी प्रकार का कंटेनर है। इसके विपरीत, जब मैं x.len() पढ़ता हूं, मुझे पहले ही यह पता होना चाहिए कि एक्स किसी प्रकार का कंटेनर है जो एक इंटरफेस को कार्यान्वित करता है या एक मानक लेन() के वर्ग से विरासत में होता है। उस भ्रम की गवाह करें जो कभी-कभी होती है जब एक वर्ग जो मैपिंग को कार्यान्वित नहीं कर रहा है उसे प्राप्त() या कुंजी() विधि है, या कुछ ऐसा है जो फ़ाइल नहीं है() विधि है।

एक ही चीज़ को एक और तरीके से कहकर, मैं एक अंतर्निहित ऑपरेशन के रूप में 'लेन' देखता हूं। मैं इसे खोने से नफरत करता हूं।/.../

+22

उन लोगों के लिए जो नहीं जानते हैं, एचसीआई मानव-कंप्यूटर इंटरफेस का खड़ा है। तो जब गिडो कहते हैं कि उन्होंने "एचसीआई कारणों" के लिए निर्णय लिया है तो उन्होंने कहा है कि उन्होंने सोचा था कि यह कोड को और अधिक पठनीय बना दिया गया है। –

+0

@ थॉमस: पायथन बिटवाई के लिए '|' का उपयोग करता है या सी की तरह ही करता है। – dan04

+1

वह जगह जहां ग्विडो सामान्य कार्यों का तर्क देता है, विधियों से बेहतर है। दिमाग चकमा देता है। :/ –

2

शायद आप __len__ देख रहे हैं। यदि वह विधि मौजूद है, तो लेन (ए) इसे कॉल करता है:

>>> class Spam: 
... def __len__(self): return 3 
... 
>>> s = Spam() 
>>> len(s) 
3 
10

यह बस नहीं है।

हालांकि, आप कर सकते हैं:

>>> [1,2,3].__len__() 

3 

एक वर्ग के लिए एक __len__() विधि len() जादू काम करता है क्या है जोड़ना।

2

ठीक है, वहाँ वास्तव में लंबाई विधि है, यह सिर्फ छिपा हुआ है:

>>> a_list = [1, 2, 3] 
>>> a_list.__len__() 
3 

लेन() में निर्मित समारोह बस छिपा लेन के लिए एक कॉल के लिए एक आवरण हो गया लगता है() वस्तु की विधि।

यह सुनिश्चित नहीं है कि उन्होंने इस तरह चीजों को लागू करने का निर्णय क्यों लिया।

11

संक्षिप्त उत्तर: 1) पिछड़ा संगतता और 2) वास्तव में इसके लिए कोई अंतर नहीं है। अधिक विस्तृत स्पष्टीकरण के लिए, पढ़ें।

ऐसे परिचालनों के लिए बेवकूफ पायथन दृष्टिकोण विशेष विधियां हैं जिन्हें सीधे कॉल करने का इरादा नहीं है। उदाहरण के लिए, x + y अपनी खुद की कक्षा के लिए काम करने के लिए, आप __add__ विधि लिखते हैं।यह सुनिश्चित करने के लिए कि int(spam) आपकी कस्टम क्लास को सही ढंग से परिवर्तित करता है, __int__ विधि लिखें। यह सुनिश्चित करने के लिए कि len(foo) कुछ समझदार है, __len__ विधि लिखें।

इस तरह चीजें हमेशा पाइथन के साथ रही हैं, और मुझे लगता है कि यह कुछ चीजों के लिए बहुत समझ में आता है। विशेष रूप से, यह ऑपरेटर ओवरलोडिंग को लागू करने के लिए एक समझदार तरीका की तरह लगता है। बाकी के लिए, अलग-अलग भाषा असहमत हैं; रूबी में आप कहने के बजाय spam.to_i पर कॉल करके कुछ पूर्णांक में परिवर्तित कर देंगे।

आप सही हैं कि पायथन एक अत्यंत ऑब्जेक्ट उन्मुख भाषा है और इसकी लंबाई को प्राप्त करने के लिए ऑब्जेक्ट पर बाहरी फ़ंक्शन को कॉल करना अजीब लगता है। दूसरी तरफ, len(silly_walks)silly_walks.len() से अधिक कठिन नहीं है, और गिडो ने कहा है कि वह वास्तव में इसे पसंद करता है (http://mail.python.org/pipermail/python-3000/2006-November/004643.html)।

+3

आह ... अंत में यह सब समझ गया। लेन() एक ऑपरेटर का अधिक है जो वास्तव में एक समारोह है। – Nate

5

इस तरह की शेष भाषा के साथ बेहतर तरीके से फिट बैठता है। पायथन में सम्मेलन यह है कि आप __foo__ वस्तुओं को विशेष क्षमताओं (उदाहरण के लिए एक विशिष्ट आधार वर्ग से प्राप्त करने के बजाय) बनाने के लिए विशेष तरीकों को जोड़ते हैं। उदाहरण के लिए, एक वस्तु

  • प्रतिदेय है अगर यह एक __call__ विधि
  • iterable है कि यह एक __iter__ विधि,
  • [] अगर यह __getitem__ और __setitem__ है साथ पहुँच का समर्थन करता है।
  • ...

इन विशेष तरीकों में से एक __len__ जो इसे एक लंबाई len() के साथ सुलभ है बनाता है।

2

कुछ अच्छी चीजें हैं कि क्यों कुछ चीजें कार्य करती हैं और अन्य विधियां हैं। यह वास्तव में भाषा में कुछ विसंगतियों का कारण बनता है।

http://mail.python.org/pipermail/python-dev/2008-January/076612.html

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