दिलचस्प पोस्ट
नोडजेएस में मूल स्थिर फ़ाइल सर्वर मैं एक एम्बेडेड संसाधन के "पथ" को कैसे खोज सकता हूं? ThreadPool एक्सक्लोरर ब्लॉक जब कतार पूर्ण है? कैसे आर में बैकस्लैश से बचें? कैसे उपयोगकर्ता स्थान के लिए एक Linux कर्नेल बफर mmap? सभी सफेद रिक्त स्थान को निकालने के लिए रूबी फ़ंक्शन? कार्य से जावा / स्कला समारोह को कॉल करना जावा के साथ पुनरावर्ती एक निर्देशिका से सभी फ़ाइलों की सूची मुझे PHP में डेटा भेजने के लिए एंड्रॉइड में एचटीटीपी क्लायंट के लिए वैकल्पिक विकल्प की आवश्यकता है क्योंकि यह अब समर्थित नहीं है java.util.Date क्लोन या प्रतिलिपि आंतरिक संदर्भ बेनकाब नहीं करने के लिए @id और @android के बीच अंतर: आईडी Php और mysql के साथ utf8mb4 का उपयोग करना एक्सएचटीएमएल में सभी वैध स्वयं समापन तत्व क्या हैं (जैसा कि प्रमुख ब्राउज़रों द्वारा लागू किया गया है)? JavaScript में JSON.stringify () के विकल्प स्विंग और एडब्ल्यूटी के बीच अंतर क्या है?

पायथन लैम्ब्डा समापन स्कोपिंग

मैं फ़ंक्शन के हस्ताक्षर से एक चर को समाप्त करने के लिए क्लोजर का उपयोग करने की कोशिश कर रहा हूं (यह मान है कि मूल्यों को स्टोर करने वाले शब्दकोश में मापदंडों की एक बड़ी संख्या को नियंत्रित करने के लिए इंटरफ़ेस के लिए क्यूटी सिग्नल को जोड़ने के लिए आवश्यक सभी फ़ंक्शन लिखना)

मुझे समझ में नहीं आ रहा है कि lambda का उपयोग करने का मामला दूसरे फ़ंक्शन में लिपटा क्यों नहीं है, सभी मामलों के लिए अंतिम नाम लौटाता है।

 names = ['a','b','c'] def test_fun(name,x): print name,x def gen_clousure(name): return lambda x: test_fun(name,x) funcs1 = [gen_clousure(n) for n in names] funcs2 = [lambda x: test_fun(n,x) for n in names] # this is what I want In [88]: for f in funcs1: ....: f(1) a 1 b 1 c 1 # I do not understand why I get this In [89]: for f in funcs2: ....: f(1) c 1 c 1 c 1 

Solutions Collecting From Web of "पायथन लैम्ब्डा समापन स्कोपिंग"

इसका कारण यह है कि क्लोजर (लैम्ब्दास या अन्यथा) नामों पर बंद, मान नहीं है जब आप lambda x: test_fun(n, x) परिभाषित करते हैं lambda x: test_fun(n, x) , n का मूल्यांकन नहीं किया जाता है, क्योंकि यह फ़ंक्शन के अंदर है। इसका मूल्यांकन तब किया जाता है जब फ़ंक्शन कहा जाता है , उस समय उस मूल्य का जो लूप से अंतिम मान होता है।

आप शुरू में कहते हैं कि आप "फ़ंक्शन हस्ताक्षर से एक चर को समाप्त करने के लिए बंद करने का उपयोग करना चाहते हैं", लेकिन यह वास्तव में इस तरह से काम नहीं करता है। (नीचे देखें, यद्यपि, एक तरीका है जो आपको संतुष्ट कर सकता है, "आप" से क्या मतलब है, इसके आधार पर)। फ़ंक्शन के परिभाषित होने पर फ़ंक्शन बॉडी के अंदर वेरिएबल का मूल्यांकन नहीं किया जाएगा। फ़ंक्शन को फ़ंक्शन-डेफिनिशन समय पर मौजूद के रूप में चर के "स्नैपशॉट" लेने के लिए, आपको चर को एक तर्क के रूप में पास करना होगा। ऐसा करने का सामान्य तरीका फ़ंक्शन को तर्क देना है जिसका डिफ़ॉल्ट मान बाह्य क्षेत्र से चर है। इन दो उदाहरणों के बीच के अंतर को देखें:

 >>> stuff = [lambda x: n+x for n in [1, 2, 3]] >>> for f in stuff: ... print f(1) 4 4 4 >>> stuff = [lambda x, n=n: n+x for n in [1, 2, 3]] >>> for f in stuff: ... print f(1) 2 3 4 

दूसरे उदाहरण में, n को उस फ़ंक्शन के n के मौजूदा मान में "लॉक इन" फ़ंक्शन के तर्क के रूप में पास करना। आपको इस तरह कुछ करना होगा यदि आप मूल्य में इस तरह से लॉक करना चाहते हैं। (यदि यह इस तरह से काम नहीं करता है, तो वैश्विक वैरिएबल जैसी चीजें बिल्कुल काम नहीं करेंगी, यह जरूरी है कि उपयोग के समय मुफ्त चर देखा जाए।)

ध्यान दें कि इस व्यवहार के बारे में कुछ भी लैम्ब्दास के लिए विशिष्ट नहीं है यदि आप किसी फ़ंक्शन को परिभाषित करने के लिए def का उपयोग करते हैं, तो समान स्कोपिंग नियम लागू हो सकते हैं, जो कि संलग्न आवृत्ति से चर को संदर्भित करता है।

अगर आप वास्तव में चाहते हैं, तो आप अपने लौटे फ़ंक्शन पर अतिरिक्त तर्क जोड़ने से बच सकते हैं, लेकिन ऐसा करने के लिए आपको उस फ़ंक्शन को एक और समारोह में लपेट करना होगा, जैसे:

 >>> def makeFunc(n): ... return lambda x: x+n >>> stuff = [makeFunc(n) for n in [1, 2, 3]] >>> for f in stuff: ... print f(1) 2 3 4 

यहां, जब भी कहा जाता है, आंतरिक लैम्ब्डा अभी भी n के मान को देखता है। लेकिन इसका अर्थ यह है कि वैश्विक वैरिएबल नहीं रह गया है, बल्कि एक स्थानीय वैरिएबल संलग्न समारोह makeFunc अंदर है। इस लोकल वैरिएबल का एक नया मान हर बार makeFunc जाता है, makeFunc को बुलाया जाता है, और लौटा लैम्ब्डा एक क्लोजर बनाता है जो कि लोकल वैरिएबल वैल्यू बचाता है जो कि makeFunc उस makeFunc लिए प्रभावी था। इस प्रकार लूप में बनाया गया प्रत्येक फ़ंक्शन का नाम "निजी" चर है जिसे x कहते हैं। (इस सरल मामले के लिए, यह बाहरी कार्य के लिए लैम्ब्डा का प्रयोग करके भी किया जा सकता है — stuff = [(lambda n: lambda x: x+n)(n) for n in [1, 2, 3]] – – लेकिन यह कम पठनीय है।)

ध्यान दें कि आपको अभी भी अपने n को एक तर्क के रूप में पारित करना होगा, ऐसा सिर्फ इतना ही है कि यह इस तरह से कर रहा है, आप इसे उसी कार्य के लिए एक तर्क के रूप में नहीं देते हैं जो कि stuff सूची में जाने वाली हवाएं; इसके बजाए आप इसे एक सहायक फ़ंक्शन के लिए एक तर्क के रूप में पास करते हैं जो आपको उस कार्य को बनाता है जिसे आप stuff में डालना चाहते हैं। इस दो-फ़ंक्शन दृष्टिकोण का उपयोग करने का लाभ यह है कि लौटा हुआ कार्य "स्वच्छ" है और इसमें अतिरिक्त तर्क नहीं है; यह उपयोगी हो सकता है यदि आप फ़ंक्शंस लपेटते थे जो कई तर्कों को स्वीकार करते थे, तो उस स्थिति में यह याद रखना भ्रामक हो सकता है कि सूची में n तर्क कहाँ था। यह नुकसान यह है कि, ऐसा करने से, कार्य करने की प्रक्रिया अधिक जटिल होती है, क्योंकि आपको एक और संलग्न समारोह की आवश्यकता होती है।

इसका नतीजा यह है कि एक ट्रेडऑफ है: आप फ़ंक्शन-सृजन प्रक्रिया को सरल बना सकते हैं (यानी, दो नेस्टेड फ़ंक्शन के लिए कोई ज़रूरत नहीं), लेकिन फिर आपको परिणामी फ़ंक्शन को थोड़ा और अधिक जटिल बनाना होगा (अर्थात, इसमें यह अतिरिक्त n=n तर्क)। या आप फ़ंक्शन को सरल बना सकते हैं (यानी, इसमें कोई n= n तर्क नहीं है), लेकिन फिर आपको फ़ंक्शन-क्रिएशन प्रक्रिया को और अधिक जटिल बनाना चाहिए (यानी, तंत्र को कार्यान्वित करने के लिए आपको दो नेस्टेड फ़ंक्शन की आवश्यकता है)।