हाल ही में मैंने पायथन के साथ खेलना शुरू किया और मैं काम को बंद करने के तरीके में कुछ अजीबों के आसपास आया। निम्नलिखित कोड पर विचार करें:
adders=[0,1,2,3]
for i in [0,1,2,3]:
adders[i]=lambda a: i+a
print adders[1](3)
यह एक सरल इनपुट बनाता है जो एकल इनपुट लेता है और उस इनपुट को किसी संख्या द्वारा जोड़ा जाता है। फंक्शंस का निर्माण forलूप में किया जाता है, जहां से इटरेटर iचलता 0है 3। इनमें से प्रत्येक संख्या के लिए एक lambdaफंक्शन बनाया जाता है जो कैप्चर करता है iऔर इसे फंक्शन के इनपुट में जोड़ता है। अंतिम पंक्ति एक पैरामीटर के रूप में दूसरे lambdaफ़ंक्शन को कॉल करती है 3। मेरे आश्चर्य के लिए आउटपुट था 6।
मैं एक उम्मीद 4। मेरा तर्क यह था: अजगर में सब कुछ एक वस्तु है और इस प्रकार हर चर इसके लिए एक सूचक है। इसके लिए lambdaक्लोजर बनाते समय i, मुझे उम्मीद थी कि वर्तमान में इंगित किए गए पूर्णांक ऑब्जेक्ट के लिए एक पॉइंटर को स्टोर करना होगा i। इसका मतलब है कि जब iएक नया पूर्णांक ऑब्जेक्ट सौंपा गया है तो यह पहले से निर्मित क्लोजर को प्रभावित नहीं करना चाहिए। अफसोस की बात है, addersएक डिबगर के भीतर सरणी का निरीक्षण करना दर्शाता है कि यह करता है। सभी lambdaकार्यों का अंतिम मान को देखें i, 3में है, जो परिणाम adders[1](3)लौटने 6।
जो मुझे निम्नलिखित के बारे में आश्चर्यचकित करते हैं:
- क्लोज़र वास्तव में क्या कैप्चर करते हैं?
lambdaवर्तमान मूल्य कोiइस तरह से कैप्चर करने के लिए फ़ंक्शंस को समझाने का सबसे सुरुचिपूर्ण तरीका क्या है जोiइसके मूल्य को बदलने पर प्रभावित नहीं होगा ?
iछोड़ता है?
print iलूप के बाद काम नहीं करेगा। लेकिन मैंने इसे अपने लिए परीक्षण किया और अब मैं देखता हूं कि आपका क्या मतलब है - यह काम करता है। मुझे नहीं पता था कि अजगर में लूप बॉडी के बाद लूप वैरिएबल लिंचिंग करता है।
if, with, tryआदि