2012-08-09 18 views
5
def f1(n): #accepts one argument 
    pass 

def f2(): #accepts no arguments 
    pass 

FUNCTION_LIST = [(f1,(2)), #each list entry is a tuple containing a function object and a tuple of arguments 
       (f1,(6)), 
       (f2,())] 

for f, arg in FUNCTION_LIST: 
    f(arg) 

लूप में तीसरी बार राउंड, यह किसी फ़ंक्शन को तर्कों के खाली टुपल को पास करने का प्रयास करता है जो कोई तर्क स्वीकार नहीं करता है। यह त्रुटि TypeError: f2() takes no arguments (1 given) देता है। पहले दो फ़ंक्शन कॉल सही ढंग से काम करते हैं - सामग्री टुपल पास हो जाती है, न कि टुपल स्वयं।पायथन - फ़ंक्शन/तर्क टुपल्स की सूची

हमलावर सूची प्रविष्टि में तर्कों की खाली टपल से छुटकारा समस्या का समाधान नहीं करता है: ValueError: need more than 1 value to unpack में

FUNCTION_LIST[2] = (f2,) 
for f,arg in FUNCTION_LIST: 
    f(arg) 

का परिणाम है।

मैंने सूची तत्वों के बजाय इंडेक्स पर फिर से प्रयास करने का भी प्रयास किया है।

for n in range(len(FUNCTION_LIST)): 
    FUNCTION_LIST[n][0](FUNCTION_LIST[n][1]) 

यह वही TypeError पहले मामले में, और IndexError: tuple index out of range देता है जब सूची की तीसरी प्रविष्टि (f2,) है।

अंत में, तारांकन नोटेशन या तो काम नहीं करता है। f1 को फोन पर इस समय यह त्रुटि:

for f,args in FUNCTION_LIST: 
    f(*args) 

TypeError: f1() argument after * must be a sequence, not int देता है।

मैं कोशिश करने के लिए चीजों से बाहर चला गया है। मुझे अभी भी लगता है कि पहले व्यक्ति को काम करना चाहिए। क्या कोई मुझे सही दिशा दिखा सकता है?

उत्तर

8

इस कोड स्निपेट में आपकी टिप्पणी एक गलत धारणा है कि इस संदर्भ में प्रासंगिक पता चलता है:

FUNCTION_LIST = [(f1,(2)), #each list entry is a tuple containing a function object and a tuple of arguments 
       (f1,(6)), 
       (f2,())] 

भाव (2) और (6) tuples नहीं हैं - वे पूर्णांक हैं। आपको सिंगल-एलिमेंट टुपल्स को इंगित करने के लिए (2,) और (6,) का उपयोग करना चाहिए। इस फिक्सिंग के बाद, अपने पाश कोड इस प्रकार दिखना चाहिए:

for f, args in FUNCTION_LIST: 
    f(*args) 

*args वाक्य रचना के लिए स्पष्टीकरण अजगर ट्यूटोरियल में Unpacking Argument Lists देखें।

(6) 

मूल्य पूर्णांक मूल्यांकन करता है और आप टपल की जरूरत है, तो इस तरह से लिखना:

+0

महान उत्तर के लिए धन्यवाद।अनुवांशिक प्रश्न: क्या कार्यों के वापसी मूल्य पर संचालन करना संभव है? मान लें कि मैं पहली प्रविष्टि को दोगुना करना चाहता था: 'FUNCTION_LIST = [(f1 * 2, (2,)), (f1, (6,)), (f2,())]' काम नहीं करेगा, ऐसा होगा, क्योंकि आप गुणा ऑपरेशन को फ़ंक्शन _object_ पर लागू करने की कोशिश कर रहे हैं, फ़ंक्शन द्वारा दिए गए मान को नहीं। –

+0

संबंधित: क्या तर्कों में अन्य कार्यों को कॉल करना संभव है, जिसे फ़ंक्शन कहा जाता है, जिसका मूल्यांकन किया जाएगा? 'FUNCTION_LIST = [(f1, (time.time(),)), (f1, (6,)), (f2,())] 'मुझे कुछ समय-निर्भर नहीं देगा, क्योंकि समय पर कॉल। जब सूची आबादी होती है तो समय() का मूल्यांकन किया जाएगा। –

+1

@poorsod: देरी निष्पादन के लिए, आपको अपने इच्छित कार्यों को परिभाषित करना चाहिए। उदाहरण के लिए 'def double_f1 (x): वापसी 2 * f1 (x) 'या' def f1_time(): f1 (time.time) वापसी करें। कुछ मामलों में, आप 'लैम्ब्डा' कार्यों से दूर हो सकते हैं, लेकिन मैं कम से कम उपयोग करने की सलाह दूंगा। –

0

() के बजाय *() पास करने का प्रयास करें। * प्रतीक पाइथन को इसके बाद के पुनरावर्तनीय को अनपैक करने के लिए कहता है, इसलिए यह खाली ट्यूपल को अनपैक करता है और फ़ंक्शन को कुछ भी नहीं देता है, क्योंकि ट्यूपल खाली था।

2

समस्या यह है कि इस तरह के अंकन है

(6,) 

और अपने तारांकन अंकन सफल होगा।

0

रिकॉर्ड के लिए, मैंने पाया है कि एक अच्छा विकल्प functools.partial का उपयोग है। निम्नलिखित कोड करता है जो मैं करने की कोशिश कर रहा था:

from functools import partial 

def f1(n): #accepts one argument 
    pass 

def f2(): #accepts no arguments 
    pass 

FUNCTION_LIST = [partial(f1,2), #each list entry is a callable with the argument pre-ordained 
       partial(f1,6), 
       partial(f2)] #the call to partial is not really necessary for the entry with no arguments. 

for f in FUNCTION_LIST: f()