Übergeben von Schlüsselwortargumenten an eine Funktion, wenn lokale Variablennamen mit den Funktionsparameternamen gleich sind
-
28-10-2019 - |
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.
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)