2012-08-05 16 views
14

Ich habe ein Python-Skript gemacht, das Funktionen auf der Grundlage der Benutzereingabe aufruft. Bisher rief ich Argument lose Funktionen einfach durch eine dictÜbergabe keine Argumente beim Aufruf der Funktion durch das dict

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

Jetzt habe ich in einer Situation bin, wo ich brauche ein paar Funktionen mit Argumenten zu nennen. Ich bin neu in Python und ich versuchte, so etwas wie diese

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

ich weiß, warum None hier nicht funktioniert, und habe es nur geschrieben symbolisieren, dass die Funktion keine Argumente übernehmen. Welche Änderungen sollte ich im Code vornehmen, damit er für alle Arten von Funktionen funktioniert?

Ich habe versucht, empty dict auszupacken, aber es funktioniert auch nicht.

Antwort

25

None ist immer noch ein Wert, und es an eine Funktion übergeben, die keine Argumente erwartet, wird nicht funktionieren. sollten Sie stattdessen partial hier

mit
from functools import partial 

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

options[choice]() 
+0

Häkchen für den eleganten Weg! Danke :) – nims

18

eine Liste von Argumenten verwenden:

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

Wenn Sie auch benannte Argumente in der Lage sein möchten, angeben, können Sie es wie folgt verlängern:

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 auch ** kwargs mit als auch als dict nach * args – jamylak

+0

@jamylak gespeichert betrachten könnte: Gute Idee, werde ich das zu meinem Beitrag hinzufügen. – phant0m

+2

@jamylak: Oh, danke für die Bearbeitung, jetzt war das ein Entpacken scheitern :) – phant0m

4

Sie könnten Lambda-Ausdrücke für die Funktionen mit Argumenten verwenden (und lassen die, ohne, wie Sie sie jetzt haben):

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

Ich bevorzuge die "partielle" Lösung, es ist der beste Weg, diesen Ansatz zu machen. – jamylak

+2

Vereinbart, es erlaubt auch, zusätzliche Parameter elegant zu übergeben. – phant0m

+0

Was ist der große Vorteil in diesem Fall? –

1

versuchen, etwas wie folgt aus:

Verwenden Sie * in Funktion Header, es sammelt alle Argumente in einem Tupel.

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,)] 
Verwandte Themen