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 la n ° 1 est-elle la bonne solution et la n ° 2 la mauvaise? **kwargs
est fondamentalement un dict, donc si je veux transmettre l'argument à openX, je pense que la bonne façon serait de ne pas **
donner le dict. Mais python n'aime évidemment pas le second et me dit que j'ai donné 3 arguments au lieu de 2. Alors, quelle est la raison derrière cela?
**args
dans le code. C'est peut-être le pire nom possible, car les gens le confondront avec*args
Réponses:
Dans le deuxième exemple, vous fournissez 3 arguments: nom de fichier, mode et un dictionnaire (
kwargs
). Mais Python attend: 2 arguments formels plus des arguments de mots-clés.En préfixant le dictionnaire par «**», vous décompressez le dictionnaire
kwargs
en arguments de mots-clés.Un dictionnaire (type
dict
) est une variable unique contenant des paires clé-valeur.Les "arguments de mots clés" sont des paramètres de méthode clé-valeur.
Tout dictionnaire peut être décompressé en arguments de mot-clé en le préfixant
**
lors de l'appel de fonction.la source
La
**
syntaxe indique à Python de collecter les arguments de mot-clé dans un dictionnaire. Le lesave2
transmet comme un argument non-mot-clé (un objet de dictionnaire). LeopenX
ne voit aucun argument de mot-clé donc le**args
n'est pas utilisé. Il obtient plutôt un troisième argument non-mot-clé (le dictionnaire). Pour résoudre ce problème, modifiez la définition de laopenX
fonction.la source
En développant la réponse de @gecco, voici un exemple qui vous montrera la différence:
Ici vous pouvez voir comment déballer un dictionnaire et pourquoi l'envoi d'un dictionnaire échoue
la source
Parce qu'un dictionnaire est une valeur unique. Vous devez utiliser l'expansion des mots clés si vous souhaitez le transmettre sous forme de groupe d'arguments de mots clés.
la source
Pour # 2, les arguments seront uniquement 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/
la source