Le passage des arguments mot-clé à une fonction lorsque les noms de variables locales sont les mêmes que les noms des paramètres de fonction

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

Question

Est-il possible d'écrire plus succint cela?

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

Arrière-plan: J'ai une fonction avec trop d'arguments

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

Je mon programme, j'ai des variables locales qui sont nommés exactement les mêmes que les paramètres de la fonction.

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

Je voudrais appeler la fonction avec des arguments de mots clés. Étant donné que les variables sont le même nom, voici comment l'appel regarderait.

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

Bien sûr, je peux passer les aruguments en utilisant la position au lieu de mots-clés comme celui-ci

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

Mais a, b, c, d, e ne sont que les noms des variables dans cet exemple, et il est facile de voir l'ordre correct. Cependant, malheureusement, les variables de mon programme sont nommés plus complicatedly et il n'y a pas d'ordre naturel facilement perceptible. Donc, je aime vraiment les passer par mot-clé pour éviter toute erreur.

Était-ce utile?

La solution

Vous pouvez faire quelque chose comme ce qui suit:

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}, vous pouvez appeler votre fonction comme ceci:

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

Cela vous donne la possibilité de spécifier exactement quelles sont les variables que vous souhaitez utiliser. Une autre méthode pour ce qui n'utilise pas globals() serait d'utiliser eval(), mais il pourrait faire l'utilisation du lambda potentiellement dangereux.

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

Si vous préférez passer locals() en argument au lieu d'utiliser globals() dans le lambda, vous pouvez utiliser ce qui suit:

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

Merci à senderle pour les suggestions de locals().

Autres conseils

locals() donne à vos variables locales, vous pouvez donc faire

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

mais vous pouvez certainement voir comment très fragile c'est.

Pourquoi ne pas utiliser kw ** ici?

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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top