"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > गैर-नेस्टेड लैम्ब्डा क्लोजर में परिवर्तनीय स्कोपिंग मुद्दों को कैसे संभालें?

गैर-नेस्टेड लैम्ब्डा क्लोजर में परिवर्तनीय स्कोपिंग मुद्दों को कैसे संभालें?

2024-11-07 को प्रकाशित
ब्राउज़ करें:708

How to Handle Variable Scoping Issues in Non-Nested Lambda Closures?

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

समस्या

फ़ंक्शन हस्ताक्षरों से उन्हें हटाने के लिए क्लोजर के भीतर वेरिएबल्स को एनकैप्सुलेट करना एक ऐसी तकनीक है जिसका उपयोग अक्सर कुशल कोड संरचना के लिए किया जाता है। हालाँकि, गैर-नेस्टेड लैम्ब्डा के मामले में, क्लोजर वेरिएबल के अंतिम मान को बरकरार रखता है, जिससे पुनरावृत्त वेरिएबल के आधार पर विशिष्ट मानों तक पहुंचने का प्रयास करते समय समस्याएं पैदा होती हैं।

प्रदान किए गए कोड स्निपेट पर विचार करें:

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]

# Expected output for funcs1
for f in funcs1:
    f(1)

# Unexpected output for funcs2 (returns last element for all cases)
for f in funcs2:
    f(1)

प्रभावी क्लोजर उपयोग के लिए इस विसंगति के पीछे के कारण को समझना महत्वपूर्ण है।

उत्तर

इस स्थिति में मौलिक अवधारणा है क्लोजर में परिवर्तनीय स्कोपिंग । क्लोजर स्वाभाविक रूप से उनके मानों के बजाय वेरिएबल नाम रखते हैं। इसका मतलब यह है कि वेरिएबल का मूल्यांकन तब होता है जब लैम्ब्डा निष्पादन शुरू होता है, न कि लैम्ब्डा परिभाषा के समय।

funcs2 के मामले में, जब आप लैम्ब्डा x निष्पादित करते हैं: test_fun(n, x), वेरिएबल n लैम्ब्डा परिभाषा के दौरान मूल्यांकन नहीं किया जाता है। इसके बजाय, मूल्यांकन केवल लैम्ब्डा कॉल पर होता है। उस बिंदु पर, n लूप से अंतिम मान रखता है (जो इस उदाहरण में 'c' है)। नतीजतन, फ़ंक्शन f हमेशा इनपुट x की परवाह किए बिना, n के मान के रूप में 'c' का उपयोग करता है।

इस समस्या को हल करने और वांछित कार्यक्षमता प्राप्त करने के लिए, वेरिएबल n को लैम्ब्डा फ़ंक्शन के दायरे में कैप्चर किया जाना चाहिए। इसे वेरिएबल को तर्क के रूप में पास करके लैम्ब्डा में प्राप्त किया जा सकता है, जैसा कि निम्नलिखित में दिखाया गया है:

funcs2 = [lambda x: test_fun(n, x) for n in names if 2 > 0]

इस अतिरिक्त इफ-स्टेटमेंट को शामिल करके जो हमेशा सत्य होता है, हम लैम्ब्डा को एन के मान को एक तर्क के रूप में लेने के लिए मजबूर करते हैं, जिससे सभी मामलों में अपेक्षित वैयक्तिकृत व्यवहार सुनिश्चित होता है।

रैप्ड लैम्ब्डा के साथ विकल्प

वैकल्पिक रूप से, आप गैर-नेस्टेड लैम्ब्डा को एक नेस्टेड फ़ंक्शन में लपेट सकते हैं, जिससे दायरे में अघोषित चर तक पहुंच को प्रभावी ढंग से रोका जा सकता है। निम्नलिखित कोड इस दृष्टिकोण को दर्शाता है:

def makeFunc(n):
    return lambda x: x n

stuff = [makeFunc(n) for n in [1, 2, 3]]

for f in stuff:
    print(f(1))

यहां, वेरिएबल n को फ़ंक्शन makeFunc में कैप्चर किया गया है, जो लैम्ब्डा के भीतर उचित स्कोपिंग सुनिश्चित करता है।

निष्कर्ष

वेरिएबल स्कोपिंग को समझना और प्रबंधित करना प्रभावी कोड डिज़ाइन और डिबगिंग के लिए इन क्लोज़र आवश्यक है। मुख्य बातें इस प्रकार हैं:

  • क्लोजर में वेरिएबल नाम होते हैं, मान नहीं
  • वेरिएबल मूल्यांकन लैम्ब्डा निष्पादन के दौरान होता है
  • वेरिएबल को कैप्चर करने के लिए, या तो उन्हें तर्क के रूप में पास करें या रैप करें किसी अन्य फ़ंक्शन में लैम्ब्डा
विज्ञप्ति वक्तव्य यह लेख यहां पुनर्मुद्रित है: 1729483641 यदि कोई उल्लंघन है, तो कृपया इसे हटाने के लिए स्टडी_गोलंग@163.कॉम से संपर्क करें।
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3