2009-03-25 15 views
9

Estoy buscando una mejor manera de llamar a funciones basadas en una variable en Python vs usando declaraciones if/else como a continuación. Cada código de estado tiene una función correspondientenombres de función dinámica de 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) 
... 

Asumo esto requerirá algún tipo de función de fábrica, pero inseguro en cuanto a la sintaxis

Respuesta

18

La forma canónica de hacerlo es usar un diccionario para emular switch o if/elif. Encontrará varias preguntas sobre problemas similares aquí en SO.

Ponga sus funciones en un diccionario con sus códigos de estado como claves:

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

funcs ['status'] levantará KeyError – SilentGhost

+0

Derecha, gracias por señalar esto. –

+0

que no está seco de todos modos – SilentGhost

37

es posible encontrar getattr útil, supongo

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

Gracias por este ejemplo, no me di cuenta de que getattr() también funcionó en los módulos – drjeep

+3

que funcionaría en cualquier objeto. los módulos también son objetos. – SilentGhost

15

asumiendo que estas funciones pertenecen a algún módulo:

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

Solo quiero saber quién votó negativamente esto ??? en serio ... – hasen

-1

algún cambio desde anterior:

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

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

y no funciona – SilentGhost

+0

Parece que debería funcionar para mí ... – Miles

+0

Esto realmente funciona – drjeep

5

que las costuras que se puede utilizar getattr en un poco diferente (en mi opinión manera más elegante)

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

o si la función se importa como abajo

from math import sin 

pecado está ahora en espacio de nombres para que pueda llamarlo por

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

me encontré con el mismo problema anteriormente. Echa un vistazo a esta pregunta, creo que es lo que estás buscando.

Dictionary or If Statements

la esperanza que esto sea útil

Eef

4

algunas mejoras a la respuesta de SilentGhost:

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

si desea llamar a la función definida en el módulo actual.

Aunque parece feo. Usaría la solución con diccionario.

Cuestiones relacionadas