2009-03-25 17 views
9

Sto cercando un modo migliore per chiamare le funzioni basate su una variabile in Python rispetto all'utilizzo di istruzioni if ​​/ else come di seguito. Ogni codice di stato ha una funzione corrispondenteNomi di funzioni dinamiche Python

if status == 'CONNECT': 
    return connect(*args, **kwargs) 
elif status == 'RAWFEED': 
    return rawfeed(*args, **kwargs) 
elif status == 'RAWCONFIG': 
    return rawconfig(*args, **kwargs) 
elif status == 'TESTFEED': 
    return testfeed(*args, **kwargs) 
... 

Presumo che ciò richiederà una sorta di funzione di fabbrica, ma incerto quanto alla sintassi

risposta

18

Il modo canonico per fare ciò è usare un dizionario per emulare switch o if/elif. Troverete molte domande su problemi simili qui su SO.

Mettere le funzioni in un dizionario con i tuoi codici di stato come tasti:

funcs = { 
    'CONNECT': connect, 
    'RAWFEED': rawfeed, 
    'RAWCONFIG' : rawconfig, 
    'TESTFEED': testfeed 
} 
funcs[status](*args, **kwargs) 
+0

funcs ['status'] solleverà KeyError – SilentGhost

+0

Giusto, grazie per averlo indicato. –

+0

che non è asciutto comunque – SilentGhost

37

si potrebbe trovare getattr utile, credo

import module 
getattr(module, status.lower())(*args, **kwargs) 
+0

Grazie per questo esempio, non mi sono reso conto che getattr() ha funzionato anche sui moduli – drjeep

+3

, avrebbe funzionato su qualsiasi oggetto. i moduli sono anche oggetti. – SilentGhost

15

assumendo che queste funzioni appartengono ad alcuni moduli:

import module 
return getattr(module, status.lower()).__call__(*args, **kwargs) 
+0

Voglio solo sapere chi ha downvoted questo ??? seriamente .. – hasen

-1

qualche cambiamento da precedente:

funcs = { 
'CONNECT': connect, 
'RAWFEED': rawfeed, 
'RAWCONFIG' : rawconfig, 
'TESTFEED': testfeed 
} 

func = funcs.get('status') 
if func: 
    func(*args, **kwargs) 
+0

e non funziona – SilentGhost

+0

Sembra che dovrebbe funzionare per me ... – Miles

+0

Questo funziona davvero – drjeep

5

cuciture che è possibile utilizzare getattr in un po 'diverso (in la mia opinione più elegante)

import math 
getattr(math, 'sin')(1) 

o se la funzione è importata come sotto

from math import sin 

peccato è ora in spazio dei nomi in modo si può chiamare da

vars()['sin'](1) 
1

ho incontrato lo stesso problema in precedenza. Dai un'occhiata a questa domanda, penso che sia quello che stai cercando.

Dictionary or If Statements

Spero che questo è utile

Eef

4

Qualche miglioramento alla risposta di SilentGhost:

globals()[status.lower()](*args, **kwargs) 

se si desidera chiamare la funzione definita nel modulo corrente.

Anche se sembra brutto. Userei la soluzione con il dizionario.

Problemi correlati