Passare gli argomenti della parola chiave a una funzione quando i nomi delle variabili locali sono uguali ai nomi dei parametri della funzione
-
28-10-2019 - |
Domanda
C'è un modo più di successione per scrivere questo?
f(a=a, b=b, c=c, d=d, e=e)
Background: ho una funzione con troppi argomenti
f(a, b, c, d, e):
pass
Il mio programma ho variabili locali che sono denominate esattamente come i parametri della funzione.
a, b, c, d, e = range(5)
Vorrei chiamare la funzione con argomenti di parole chiave. Poiché le variabili sono chiamate uguali, ecco come sarebbe la chiamata.
g = f(a=a, b=b, c=c, d=d, e=e) # this can get very long
Naturalmente, posso passare gli svumenti usando la posizione anziché le parole chiave come questa
g = f(a, b, c, d, e)
Ma a
, b
, c
, d
, e
sono solo i nomi delle variabili in questo esempio ed è facile vedere l'ordine corretto. Tuttavia, sfortunatamente le variabili nel mio programma sono nominate in modo più complicato e non esiste un ordine naturale facilmente riconoscibile. Quindi mi piace molto passarli per parola chiave per evitare errori.
Soluzione
Potresti fare qualcosa come i seguenti:
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}
, quindi puoi chiamare la tua funzione in questo modo:
f(**arg_dict('a, b, c, d, e'))
Questo ti dà la possibilità di specificare esattamente quali variabili si desidera utilizzare. Un metodo alternativo per questo che non utilizza globals()
sarebbe usare eval()
, ma potrebbe rendere potenzialmente pericoloso l'uso della lambda.
arg_dict = lambda l: dict(zip(l.split(', '), eval(l)))
Se preferisci passare locals()
come argomento invece di usare globals()
Nella lambda puoi usare quanto segue:
arg_dict = lambda l, d=locals(): dict((k, d[k]) for k in l.split(', '))
f(**arg_dict('a, b, c, d, e'))
Grazie a Senderle per il locals()
suggerimenti.
Altri suggerimenti
locals()
dà le tue variabili locali, così potresti farlo
def somewhere():
x = 3 # its a local
f(**locals()) # same as f(x=3)
Ma puoi sicuramente vedere quanto sia fragile.
Perché non puoi usare ** kw qui?
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)