2009-03-25 11 views
9

Je cherche un meilleur moyen d'appeler des fonctions basées sur une variable en Python vs en utilisant des instructions if/else comme ci-dessous. Chaque code d'état a une fonction correspondanteNoms de fonctions dynamiques 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) 
... 

Je suppose que cela nécessitera une sorte de fonction de l'usine, mais pas certain de la syntaxe

Répondre

18

La manière canonique de faire ceci est d'utiliser un dictionnaire pour émuler switch ou if/elif. Vous trouverez plusieurs questions à des problèmes similaires ici sur SO.

Mettez vos fonctions dans un dictionnaire avec vos codes d'état en tant que clés:

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

funcs ['status'] va augmenter KeyError – SilentGhost

+0

Droit, merci de le signaler. –

+0

ce n'est pas sec de toute façon – SilentGhost

37

vous pourriez trouver getattr utile, je suppose que

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

Merci pour cet exemple, je ne savais pas getattr() a également travaillé sur les modules – drjeep

+3

il fonctionnerait sur n'importe quel objet. les modules sont aussi des objets. – SilentGhost

15

en supposant que ces fonctions appartiennent à un module:

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

Je veux juste savoir qui a déprimé cela ??? sérieux .. – hasen

-1

un changement de précédente:

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

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

et cela ne fonctionne pas – SilentGhost

+0

On dirait que cela devrait fonctionner pour moi ... – Miles

+0

Cela fonctionne en effet – drjeep

5

il coutures que vous pouvez utiliser getattr dans un peu différent (en mon opinion façon plus élégante)

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

ou si la fonction est importée comme ci-dessous

from math import sin 

péché est maintenant dans l'espace de noms pour que vous puissiez l'appeler par

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

j'ai rencontré le même problème auparavant. Jetez un oeil à cette question, je pense que c'est ce que vous cherchez.

Dictionary or If Statements

Espérons que cela est utile

Eef

4

Quelques améliorations à la réponse de SilentGhost:

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

si vous voulez appeler la fonction définie dans le module courant.

Bien que cela semble laid. J'utiliserais la solution avec un dictionnaire.