2014-05-02 20 views
9

Bei einer Funktion höherer Ordnung, die mehrere Funktionen als Argumente übernimmt, wie könnte diese Funktion Schlüsselwortargumente an die Funktionsargumente übergeben?Trennen von ** kwargs für verschiedene Funktionen

Beispiel

def eat(food='eggs', how_much=1): 
    print(food * how_much) 


def parrot_is(state='dead'): 
    print("This parrot is %s." % state) 


def skit(*lines, **kwargs): 
    for line in lines: 
     line(**kwargs) 

skit(eat, parrot_is) # eggs \n This parrot is dead. 
skit(eat, parrot_is, food='spam', how_much=50, state='an ex-parrot') # error 

state ist kein Schlüsselwort arg von eat so wie nur Schlüsselwort args relevant die Funktion übergeben Skit können, die sie anrufen wird?

+4

Kein Zweifel, es gibt Möglichkeiten, dies zu tun, aber ich denke, Sie dies aus dem falschen Winkel sind nähern. Was würden Sie tun, wenn zwei Ihrer Funktionen ein Schlüsselwort arg mit demselben Namen annehmen und Sie den beiden Funktionen unterschiedliche Werte übergeben möchten? Am besten geben Sie explizit dicts of keyword args ein. Potentiell wäre jedes Argument (sagen wir) ein Zwei-Element-Tupel, das aus einer Funktion und ihrem Dict von Schlüsselwort-Argumenten besteht. – Hammerite

+0

Das ist wahrscheinlich die beste Lösung. – cheezsteak

Antwort

8

können Sie filtern das kwargs Wörterbuch basiert auf func_code.co_varnames einer Funktion:

def skit(*lines, **kwargs): 
    for line in lines: 
     line(**{key: value for key, value in kwargs.iteritems() 
       if key in line.func_code.co_varnames}) 

Siehe auch: Can you list the keyword arguments a Python function receives?

+2

+1 oder verwenden Sie 'inspect.getargspec (line) .args'. –

+0

@A श wini च haudhary danke, guter Punkt, wie immer hilfreich. Ich habe auch einen Link zum zugehörigen Thread hinzugefügt. – alecxe

+0

Was ist der Vorteil von inspect.getargspec (func) .args über line.func_code.co_varnames? Bietet das Inspektionsmodul dann einfach mehr Möglichkeiten, die wir in diesem Fall nicht benötigen? – cheezsteak

6

Wenn Sie **kwargs auf alle Definitionen hinzufügen, können Sie die ganze Menge passieren:

def eat(food='eggs', how_much=1, **kwargs): 
    print(food * how_much) 


def parrot_is(state='dead', **kwargs): 
    print("This parrot is %s." % state) 


def skit(*lines, **kwargs): 
    for line in lines: 
     line(**kwargs) 

Alles in **kwargs das ist nicht auch ein explizites Schlüsselwort Argument wird nur l in kwargs eingegeben und von z.B. eat.

Beispiel:

>>> skit(eat, parrot_is, food='spam', how_much=50, state='an ex-parrot') 
spamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspamspam 
This parrot is an ex-parrot. 
Verwandte Themen