Übergeben von Schlüsselwortargumenten an eine Funktion, wenn lokale Variablennamen mit den Funktionsparameternamen gleich sind

StackOverflow https://stackoverflow.com/questions/5860974

Frage

Gibt es eine Succint -Möglichkeit, dies zu schreiben?

f(a=a, b=b, c=c, d=d, e=e)

Hintergrund: Ich habe eine Funktion mit zu vielen Argumenten

f(a, b, c, d, e):
    pass

Ich mein Programm habe lokale Variablen, die genau wie die Funktionsparameter genannt werden.

a, b, c, d, e = range(5)

Ich möchte die Funktion mit Keyword -Argumenten aufrufen. Da die Variablen gleich genannt werden, würde der Anruf so aussehen.

g = f(a=a, b=b, c=c, d=d, e=e) # this can get very long

Natürlich kann ich die Augumente mit Position anstelle von Schlüsselwörtern wie diesen übergeben

g = f(a, b, c, d, e) 

Aber a, b, c, d, e sind nur die Namen von Variablen in diesem Beispiel und es ist leicht, die richtige Reihenfolge zu erkennen. Leider werden die Variablen in meinem Programm jedoch komplizierter genannt und es gibt keine leicht erkennbare natürliche Ordnung. Ich gehe sie also sehr gerne mit Schlüsselwort aus, um Fehler zu vermeiden.

War es hilfreich?

Lösung

Sie könnten so etwas wie Folgendes machen:

a, b, c, d, e = range(5)
arg_dict = lambda l: dict((k, globals()[k]) for k in l.split(', '))

arg_dict('a, b, c, d, e') => {'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3}, Sie können Ihre Funktion so aufrufen:

f(**arg_dict('a, b, c, d, e'))

Auf diese Weise können Sie genau angeben, welche Variablen Sie verwenden möchten. Eine alternative Methode dafür, die nicht verwendet wird globals() wäre zu benutzen eval(), aber es könnte die Verwendung der Lambda möglicherweise unsicher machen.

arg_dict = lambda l: dict(zip(l.split(', '), eval(l)))

Wenn Sie lieber bestehen möchten locals() in als Argument anstatt zu verwenden globals() In der Lambda können Sie Folgendes verwenden:

arg_dict = lambda l, d=locals(): dict((k, d[k]) for k in l.split(', '))
f(**arg_dict('a, b, c, d, e'))

Dank an Absender für die locals() Anregungen.

Andere Tipps

locals() gibt Ihren lokalen Variablen, so dass Sie dies tun könnten

def somewhere():
  x = 3 # its a local
  f(**locals()) # same as f(x=3)

Aber Sie können sicher sehen, wie sehr zerbrechlich das ist.

Warum können Sie hier nicht ** kw verwenden?

def foo(**kw):
    for k,v in kw.items():
       print k,v


foo(a=2)
foo(a=3, b=4)
foo(nonsene=True, blather=False)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top