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)
La terza volta nel ciclo, tenta di passare una tupla vuota di argomenti a una funzione che non accetta argomenti. Dà l'errore TypeError: f2() takes no arguments (1 given)
. Le prime due chiamate di funzione funzionano correttamente: viene inviato il contenuto della tupla, non la tupla stessa.Python - elenco di funzioni/argomento tuple
sbarazzarsi del tupla vuota di argomenti nella voce della lista incriminata non risolve il problema:
FUNCTION_LIST[2] = (f2,)
for f,arg in FUNCTION_LIST:
f(arg)
risultati in ValueError: need more than 1 value to unpack
.
Ho anche provato a ripetere l'indice piuttosto che gli elementi della lista.
for n in range(len(FUNCTION_LIST)):
FUNCTION_LIST[n][0](FUNCTION_LIST[n][1])
Questo dà lo stesso TypeError
nel primo caso, e IndexError: tuple index out of range
quando la terza voce della lista è (f2,)
.
Infine, la notazione asterisco non funziona. Questa volta gli errori sulla chiamata a f1
:
for f,args in FUNCTION_LIST:
f(*args)
dà TypeError: f1() argument after * must be a sequence, not int
.
Ho esaurito le cose da provare. Penso ancora che il primo dovrebbe funzionare. Qualcuno può indicarmi la giusta direzione?
Grazie per l'ottima risposta.Domanda corollaria: è possibile eseguire operazioni sul valore di ritorno delle funzioni? Diciamo che volevo raddoppiare la prima voce: 'FUNCTION_LIST = [(f1 * 2, (2,)), (f1, (6,)), (f2,())]' non funzionerebbe, lo farebbe, perché dovresti provare ad applicare l'operatore di moltiplicazione a una funzione _oggetto_, non il valore restituito dalla funzione. –
In relazione a quanto segue: è possibile chiamare altre funzioni nella tupla degli argomenti, che verrebbe valutata quando viene chiamata la funzione? 'FUNCTION_LIST = [(f1, (time.time(),)), (f1, (6,)), (f2,())]' non mi darebbe qualcosa in base al tempo, perché la chiamata al tempo. time() verrebbe valutato quando l'elenco è popolato. –
@poorsod: per l'esecuzione ritardata, è necessario definire le funzioni facendo ciò che si desidera. Ad esempio 'def double_f1 (x): return 2 * f1 (x)' o 'def f1_time(): return f1 (time.time)'. In alcuni casi, puoi farcela con le funzioni di 'lambda', ma ti consiglio di usarlo con parsimonia. –