हाल ही में मैंने पायथन के साथ खेलना शुरू किया और मैं काम को बंद करने के तरीके में कुछ अजीबों के आसपास आया। निम्नलिखित कोड पर विचार करें:
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
आदि