236 votes

passer l'argument **kwargs à une autre fonction avec **kwargs

Je ne comprends pas l'exemple suivant, disons que j'ai ces fonctions :

 # python likes
def save(filename, data, **kwargs):
    fo = openX(filename, "w", **kwargs) # <- #1
    fo.write(data)
    fo.close()
# python doesnt like
def save2(filename, data, **kwargs):
    fo = openX(filename, "w", kwargs) # <- #2
    fo.write(data)
    fo.close()

def openX(filename, mode, **kwargs):
    #doing something fancy and returning a file object

Pourquoi n°1 est la bonne solution et n°2 la mauvaise ? **kwargs est essentiellement un dict, donc si je veux transmettre l'argument à openX, je pense que la bonne méthode serait sans ** et en donnant simplement le dict. Mais Python n'aime évidemment pas le second et me dit que j'ai donné 3 au lieu de 2 arguments.

Alors, quelle est la raison derrière cela?

21voto

Reda Drissi Points 191

En développant la réponse de @gecco, voici un exemple qui vous montrera la différence :

 def foo(**kwargs):
    for entry in kwargs.items():
        print("Key: {}, value: {}".format(entry[0], entry[1]))

# call using normal keys:
foo(a=1, b=2, c=3)
# call using an unpacked dictionary:
foo(**{"a": 1, "b":2, "c":3})

# call using a dictionary fails because the function will think you are
# giving it a positional argument
foo({"a": 1, "b": 2, "c": 3})
# this yields the same error as any other positional argument
foo(3)
foo("string")

Vous pouvez voir ici comment fonctionne le déballage d'un dictionnaire et pourquoi l'envoi d'un dictionnaire réel échoue

14voto

Keith Points 13800

La ** indique à Python de collecter des arguments de mots-clés dans un dictionnaire. Le save2 transmet en tant qu'argument non-clé (un objet dictionnaire). Le openX ne voit aucun argument de mot-clé, donc le **args n'est pas utilisé. Il obtient à la place un troisième argument non-clé (le dictionnaire). Pour résoudre ce problème, modifiez la définition de la fonction openX .

 def openX(filename, mode, kwargs):
    pass

2voto

Kit Ho Points 4632

Pour 2 args ne sera qu'un paramètre formel avec une valeur dict, mais pas un paramètre de type mot-clé.

Si vous souhaitez passer un paramètre de type de mot-clé dans un argument de mot-clé Vous devez spécifier ** avant votre dictionnaire, ce qui signifie ** args

consultez ceci pour plus de détails sur l'utilisation de **kw

http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/

1voto

Parce qu'un dictionnaire est une valeur unique. Vous devez utiliser le développement de mots-clés si vous souhaitez le transmettre en tant que groupe d'arguments de mots-clés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X