2012-08-05 6 views
14

He hecho una secuencia de comandos de Python que llama a funciones basadas en la entrada del usuario. Hasta ahora estaba llamando a funciones de argumentos de menos simplemente a través de un diccionarioPasando sin argumentos mientras se llama a la función a través de dict

options = { 0 : func0, 
      1 : func1, 
      2 : func2, 
      } 
options[choice]() 

Ahora estoy en una situación en la que tengo que llamar a unas pocas funciones con argumentos. Soy nuevo en Python y he intentado algo como esto

options = { 0 : (func0,None), 
      1 : (func1,None), 
      2 : (func2,foo1), 
      3 : (func3,foo2), 
      } 
options[choice][0](options[choice][1]) 

Soy consciente de qué None no funciona aquí, y lo he escrito sólo para simbolizar que la función no toma ningún argumento. ¿Qué cambios debo hacer en el código para que funcione para todo tipo de funciones?

He intentado desempaquetar empty dict pero tampoco funciona.

Respuesta

25

None sigue siendo un valor, y pasarlo a una función que no está esperando argumentos no funcionará. En lugar considerar el uso de partial aquí

from functools import partial 

options = { 0: func0, 
      1: func1, 
      2: partial(func2, foo1), 
      3: partial(func3, foo2), 
      } 

options[choice]() 
+0

Marca de verificación para la manera elegante! Gracias :) – nims

18

utilizar una lista de argumentos:

options = { 0 : (func0, []), 
      1 : (func1, []), 
      2 : (func2, [foo1]), 
      3 : (func3, [foo2]), 
      } 
options[choice][0](*options[choice][1]) 
# or 
func, args = options[choice] 
func(*args) 

Si usted quiere ser capaz de especificar argumentos con nombre, así, se puede extender de esta manera:

options = { 0 : (func0, [], {}), 
      1 : (func1, [], {param_name: value}), 
      2 : (print_name, [], {name: "nims"}), 
      3 : (func3, [foo2], {}), 
      } 
func, args, kwargs = options[choice] 
func(*args, **kwargs) 
+1

OP también podría considerar la posibilidad de kwargs ** así, almacenados como un dict después args * – jamylak

+0

@jamylak: Buena idea, voy a añadir que a mi mensaje. – phant0m

+2

@jamylak: Ah, gracias por la edición, ahora que fue un paquete de descompresión :) – phant0m

4

Se puede usar expresiones lambda para las funciones con argumentos (y dejar los que no tienen a medida que los tiene ahora):

options = { 0 : func0, 
      1 : func1, 
      2 : lambda: func2(foo1), 
      3 : lambda: func3(foo2), 
      } 
+0

Prefiero la solución 'parcial', es la mejor manera de hacer este enfoque. – jamylak

+2

De acuerdo, también permite pasar parámetros adicionales con elegancia. – phant0m

+0

¿Cuál es la gran ventaja en este caso? –

1

intentar algo como esto:

use * en el encabezado de la función, recogerá todos los argumentos en una tupla.

def func0(*a): 
    print list(a) 
def func1(*a): 
    print list(a) 
def func2(*a): 
    print list(a) 
def func3(*a): 
    print list(a) 
foo1=1 
foo2=2 
options = { 0 : (func0,None), 
      1 : (func1,None), 
      2 : (func2,foo1), 
      3 : (func3,foo2), 
      } 
choice=2 
options[choice][0](options[choice][1:]) #prints [(1,)] 

choice=1 
options[choice][0](options[choice][1:]) #prints [(None,)] 
Cuestiones relacionadas