2012-08-05 12 views
14

Zrobiłem skrypt w języku Python, który wywołuje funkcje na podstawie danych wprowadzanych przez użytkownika. Do tej pory byłem wywoływania funkcji argumentów mniej prostu przez dictBrak argumentów podczas wywoływania funkcji poprzez dyktowanie

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

teraz jestem w sytuacji, gdy trzeba zadzwonić kilka funkcji z argumentami. Jestem nowym Python i próbowałem coś jak ten

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

jestem świadomy dlaczego None tu nie pracuje, i napisałem ją właśnie symbolizować, że funkcja nie przyjmuje żadnych argumentów. Jakie zmiany powinienem wprowadzić w kodzie, aby działał dla wszystkich rodzajów funkcji?

Próbowałem rozpakować empty dict, ale to też nie działa.

Odpowiedz

25

None nadal jest wartością, i przekazanie go do funkcji, która nie oczekuje argumentów, nie będzie działać. Zamiast tego należy rozważyć użycie partial tutaj

from functools import partial 

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

options[choice]() 
+0

Zaznacz znak na elegancki sposób! Dzięki :) – nims

18

użyć listy argumentów:

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

Jeśli chcesz być w stanie określić nazwanych argumentów, jak również można przedłużyć go tak:

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

PO mogłaby również rozważyć ** kwargs Jak dobrze, zapisane jako dict po * args – jamylak

+0

@jamylak: Dobry pomysł, dodam, że do mojego postu. – phant0m

+2

@jamylak: Oh, dzięki za edycję, teraz to się rozpakowało niepowodzeniem :) – phant0m

4

Można użyć wyrażenia lambda dla funkcji z argumentami (i pozostawić te bez, jak masz je teraz):

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

Wolę rozwiązanie "częściowe", jest to najlepszy sposób na zrobienie tego podejścia. – jamylak

+2

Uzgodnione, pozwala również elegancko przekazać dodatkowe parametry. – phant0m

+0

Co jest w tym przypadku wielką zaletą? –

1

spróbować czegoś takiego:

użyj * w nagłówku funkcji, to zbierze wszystkie argumenty w krotce.

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,)] 
Powiązane problemy