मान लीजिए मुझे add1, add2, ..., add10 नामक 10 फ़ंक्शन बनाने की आवश्यकता है। प्रत्येक i के लिए, addi एक पूर्णांक x लेता है और x+i आउटपुट करता है।

जब मैंने निम्नलिखित की कोशिश की और एड 2 (10) का मूल्यांकन किया तो पायथन ने मुझे एक नाम त्रुटि दी।

for i in range(10):
    def addi(x):
        return x + (i+1)

मुझे पता है कि उपरोक्त कोड गलत है, क्योंकि मेरे द्वारा परिभाषित एडी फ़ंक्शन परस्पर नहीं हैं; मुझे पूरा यकीन है कि मैंने जो कुछ किया है वह 10 बार एडी को फिर से परिभाषित करता है। इन 10 कार्यों को शीघ्रता से कैसे परिभाषित किया जा सकता है?

7
jessica 3 अप्रैल 2018, 16:20

2 जवाब

कार्य सामान्य रूप से परिवर्तनशील नहीं होते हैं; लेकिन उनके पास डेटा के संदर्भ हो सकते हैं। आपके स्निपेट में, यह संदर्भ थोड़ा अस्पष्ट है, लेकिन i फ़ंक्शन बॉडी में केवल एक बार पढ़ने के रूप में होता है। इसलिए यह कुछ बाहरी दायरे से पढ़ता है, आमतौर पर फ़ंक्शन या मॉड्यूल आपके for लूप के भीतर समाहित होता है। क्योंकि यह एक साझा संदर्भ होता है, प्रत्येक addi फ़ंक्शन उसी i के साथ समाप्त होगा।

एक और मुद्दा यह है कि आप प्रत्येक पुनरावृत्ति पर addi नाम का उपयोग कर रहे हैं, और फ़ंक्शन किसी अन्य नाम के तहत कभी नहीं दिखाई दिया। तो जो भी addi फ़ंक्शन पहले परिभाषित किए गए थे वे खो गए हैं। यह हमें तीसरे प्रश्न की ओर ले जाता है; आप गतिशील रूप से नाम (जैसे फ़ंक्शन नाम) क्यों बनाना चाहेंगे? संग्रह का उपयोग करना लगभग हमेशा बेहतर होता है, जैसे कि d jpp के उत्तर में शब्दकोश। अन्यथा, कौन सा कोड आपके द्वारा बनाए गए कार्यों को भी संदर्भित करेगा?

जो कुछ भी कहा गया है, वह अभी भी संभव है जो आपने मांगा है, हालांकि बहुत अजीब है। यहाँ एक तरीका है:

def addfunc(n):
    def addn(x):
        return x+n
    return addn

for i in range(1,10):
    globals()['add{}'.format(i)] = addfunc(i)

यह globals का दुरुपयोग करके गतिशील रूप से बनाए गए नामों को इसमें शामिल करता है मॉड्यूल का नामस्थान, और इनमें से प्रत्येक फ़ंक्शन को अपने व्यक्तिगत n मान रखने वाले नामस्थान बनाने के लिए दूसरे के भीतर घोंसला बनाता है। एक अन्य क्लासिक हैक डिफ़ॉल्ट तर्क का उपयोग कर रहा था, और आंशिक एप्लिकेशन की operator.add एक साफ-सुथरी कार्यात्मक शैली है।

4
Yann Vernier 3 अप्रैल 2018, 13:34

जैसा कि अन्य ने नोट किया है, यह संदिग्ध है यदि आपको इसे उत्पादन कोड में करना चाहिए। हालांकि, शैक्षिक उद्देश्यों के लिए, यहां फ़ंक्शन नाम उत्पन्न करके और उन्हें वैश्विक नामस्थान में इंजेक्ट करके इसे कैसे करना है:

>>> def f(x, i):
...     return x + i + 1
... 
>>> from functools import partial
>>> for i in range(10):
...     globals()['add%s' % i] = partial(f, i=i)
... 
>>> add8(5)
14
>>> add3(5)
9

functools.partial पाइथन में currying को क्रियान्वित करता है ताकि एकल फ़ंक्शन परिभाषा की एक प्रति बनाई जा सके जहां प्रत्येक "हार्डकोड" को एक या अधिक फ़ंक्शन तर्कों की प्रतिलिपि बनाएँ।

1
Erik Cederstrand 3 अप्रैल 2018, 13:44