जवाबों:
lenएक संग्रह की लंबाई पाने के लिए एक समारोह है। यह किसी ऑब्जेक्ट की __len__विधि को कॉल करके काम करता है । __something__विशेषताएं विशेष हैं और आमतौर पर आंख से मिलती है, और आम तौर पर सीधे नहीं कहा जाना चाहिए।
यह कुछ समय पहले तय किया गया था कि किसी चीज की लंबाई एक फ़ंक्शन और विधि कोड नहीं होनी चाहिए, यह तर्क देते हुए कि इसका len(a)अर्थ शुरुआती के लिए स्पष्ट a.len()होगा लेकिन उतना स्पष्ट नहीं होगा। जब पायथन शुरू __len__भी नहीं हुआ था और lenएक विशेष चीज थी जो कुछ प्रकार की वस्तुओं के साथ काम करती थी। यह स्थिति हमें छोड़ती है या नहीं, यह समझ में आता है।
यह अक्सर ऐसा होता है कि अंतर्निर्मित या ऑपरेटर के "विशिष्ट" व्यवहार में __whatever__शामिल वस्तुओं पर उपयुक्त जादू के तरीकों (जैसे नामों के साथ ) को कॉल करना (अलग और अच्छे सिंटैक्स के साथ ) होता है। अक्सर अंतर्निहित या ऑपरेटर में "अतिरिक्त मूल्य" होता है (यह इसमें शामिल वस्तुओं के आधार पर अलग-अलग पथ लेने में सक्षम होता है) - lenबनाम के मामले में __len__, यह बिल्ट-इन पर थोड़ी सी पवित्रता की जाँच है जो इसमें से गायब है जादू की विधि:
>>> class bah(object):
... def __len__(self): return "an inch"
...
>>> bah().__len__()
'an inch'
>>> len(bah())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object cannot be interpreted as an integer
जब आप lenबिल्ट-इन में कॉल देखते हैं , तो आपको यकीन है कि, यदि प्रोग्राम इसके बाद भी जारी रहता है, तो अपवाद को बढ़ाने के बजाय, कॉल ने एक पूर्णांक, गैर-ऋणात्मक और 2 ** 31 से कम लौटाया है - जब आपको एक कॉल दिखाई देता है xxx.__len__(), आपको कोई निश्चितता नहीं है (सिवाय इसके कि कोड का लेखक या तो पायथन से अपरिचित है या कोई अच्छा नहीं; ;-)
अन्य बिल्ट-इन सरल संचित जांच और पठनीयता से परे और भी अधिक मूल्य प्रदान करते हैं। बिल्डरों को कॉल करने और ऑपरेटरों के उपयोग के माध्यम से काम करने के लिए अजगर के सभी को समान रूप से डिजाइन करके, जादू के तरीकों के लिए कॉल के माध्यम से, प्रोग्रामर को यह याद रखने के बोझ से बख्शा नहीं जाता है कि कौन सा मामला है। (कभी-कभी एक त्रुटि फिसल जाती है: 2.5 तक, आपको कॉल करना था foo.next()- 2.6 में, जबकि वह अभी भी पीछे की संगतता के लिए काम करता है, आपको कॉल करना चाहिए next(foo), और 3.*, __next__"oops-eye" के बजाय मैजिक विधि को सही ढंग से नाम दिया गया है next! - )।
इसलिए सामान्य नियम यह होना चाहिए कि आप कभी भी जादू की विधि को सीधे न कहें (लेकिन हमेशा अप्रत्यक्ष रूप से एक अंतर्निहित के माध्यम से) जब तक कि आपको ठीक-ठीक पता न हो कि आपको ऐसा करने की आवश्यकता क्यों है (उदाहरण के लिए, जब आप उप-वर्ग में ऐसी विधि को ओवरराइड कर रहे हों, यदि उपवर्ग को उस सुपरक्लास को टालने की जरूरत है जो जादू की विधि से स्पष्ट रूप से किया जाना चाहिए)।
def len(x): return "I am a string." print(len(42)) print(len([1,2,3]))और यह I am stringदो बार छपी । क्या आप इसे और अधिक समझा सकते हैं?
__len__विशेष विधि (फ़ंक्शन नहीं) कहती है ।
lenकुछ अन्य फ़ंक्शन (जैसे मेरे उदाहरण में) जो उसी नाम का हुआ है - len। "आप अंतर्निहित फ़ंक्शन लेन को पुनर्परिभाषित कर रहे हैं" या इस तरह की कोई चेतावनी नहीं है। मेरी राय में, मुझे यकीन नहीं हो सकता है कि एलेक्स ने अपने जवाब में क्या कहा था।
len in vars(__builtins__).values()।
आप लेन के बारे में सोच सकते हैं () के बराबर होने के नाते
def len(x):
return x.__len__()
एक लाभ यह है कि यह आपको चीजों को लिखने की अनुमति देता है
somelist = [[1], [2, 3], [4, 5, 6]]
map(len, somelist)
के बजाय
map(list.__len__, somelist)
या
map(operator.methodcaller('__len__'), somelist)
हालांकि थोड़ा अलग व्यवहार है। उदाहरण के लिए ints के मामले में
>>> (1).__len__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__len__'
>>> len(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()
operator.methodcallerबजाय मतलब है operator.attrgetter।
आप पायथंड डॉक्स की जांच कर सकते हैं :
>>> class Meta(type):
... def __getattribute__(*args):
... print "Metaclass getattribute invoked"
... return type.__getattribute__(*args)
...
>>> class C(object):
... __metaclass__ = Meta
... def __len__(self):
... return 10
... def __getattribute__(*args):
... print "Class getattribute invoked"
... return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__() # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c) # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c) # Implicit lookup
10