la méthode de classe génère “TypeError:… a plusieurs valeurs pour l’argument de mot-clé…”

Si je définis une méthode de classe avec un argument mot-clé donc:

class foo(object): def foodo(thing=None, thong='not underwear'): print thing if thing else "nothing" print 'a thong is',thong 

L’appel de la méthode génère un TypeError :

 myfoo = foo() myfoo.foodo(thing="something") ... TypeError: foodo() got multiple values for keyword argument 'thing' 

Que se passe-t-il?

Le problème est que le premier argument passé aux méthodes de classe dans python est toujours une copie de l’instance de classe sur laquelle la méthode est appelée, généralement appelée self . Si la classe est ainsi déclarée:

 class foo(object): def foodo(self, thing=None, thong='not underwear'): print thing if thing else "nothing" print 'a thong is',thong 

il se comporte comme prévu.

Explication:

Sans self comme premier paramètre, lorsque myfoo.foodo(thing="something") est exécuté, la méthode foodo est appelée avec des arguments (myfoo, thing="something") . L’instance myfoo est alors assignée à thing (puisque thing est le premier paramètre déclaré), mais python tente également d’affecter "something" à "something" thing , d’où l’exception.

Pour démontrer, essayez d’exécuter ceci avec le code d’origine:

 myfoo.foodo("something") print print myfoo 

Vous allez sortir comme:

 <__main__ .foo object at 0x321c290> a thong is something <__main__ .foo object at 0x321c290> 

Vous pouvez voir que “thing” a été assigné une référence à l’instance “myfoo” de la classe “foo”. Cette section de la documentation explique comment les arguments de fonction fonctionnent un peu plus.

Merci pour les messages instructifs. Je voudrais juste garder une note que si vous obtenez “TypeError: foodo () a plusieurs valeurs pour l’argument mot-clé ‘chose'”, il se peut aussi que vous passiez par erreur le paramètre “self” lorsque appeler la fonction (probablement parce que vous avez copié la ligne de la déclaration de classe – c’est une erreur courante quand on est pressé).

Cela pourrait être évident, mais cela pourrait aider quelqu’un qui ne l’a jamais vu auparavant. Cela se produit également pour les fonctions normales si vous affectez par erreur un paramètre par position et explicitement par nom.

 >>> def foodo(thing=None, thong='not underwear'): ... print thing if thing else "nothing" ... print 'a thong is',thong ... >>> foodo('something', thing='everything') Traceback (most recent call last): File "", line 1, in  TypeError: foodo() got multiple values for keyword argument 'thing' 

il suffit d’append le décorateur ‘staticmethod’ à la fonction et le problème est résolu

 class foo(object): @staticmethod def foodo(thing=None, thong='not underwear'): print thing if thing else "nothing" print 'a thong is',thong 

Cette erreur peut également se produire si vous transmettez un argument de mot-clé pour lequel l’une des clés est similaire (a le même nom de chaîne) à un argument de position.

 >>> class Foo(): ... def bar(self, bar, **kwargs): ... print(bar) ... >>> kwgs = {"bar":"Barred", "jokes":"Another key word argument"} >>> myfoo = Foo() >>> myfoo.bar("fire", **kwgs) Traceback (most recent call last): File "", line 1, in  TypeError: bar() got multiple values for argument 'bar' >>> 

“fire” a été accepté dans l’argument “bar”. Et pourtant, il y a un autre argument “bar” dans kwargs.

Vous devez supprimer l’argument mot-clé de kwargs avant de le transmettre à la méthode.

Je veux append une autre réponse:

Cela se produit lorsque vous essayez de passer un paramètre de position avec un ordre de position incorrect avec un argument de mot-clé dans la fonction d’appel.

there is difference between parameter and argument vous pouvez lire en détail à propos des arguments et parameters dans python

 def hello(a,b=1, *args): print(a, b, *args) hello(1, 2, 3, 4,a=12) 

puisque nous avons trois parameters:

a est paramètre de position

b = 1 est le mot clé et le paramètre par défaut

* args est un paramètre de longueur variable

donc nous assignons d’abord un paramètre as positionnel, ce qui signifie que nous devons fournir une valeur à l’argument positionnel dans son ordre de position, ici l’ordre est important. mais nous passons l’argument 1 à la place d’une fonction d’appelante et nous fournissons également une valeur à un, en considérant comme un argument mot clé. maintenant a deux valeurs:

on est la valeur positionnelle: a = 1

seconde est la valeur en mot clé qui est a = 12

Solution

Nous devons changer hello(1, 2, 3, 4,a=12) en hello(1, 2, 3, 4,12) donc maintenant, on obtiendra une seule valeur de position qui est 1 et b obtiendra la valeur 2 et rest des valeurs obtiendra * args (paramètre de longueur variable)

Information additionnelle

si nous voulons que * args devrait obtenir 2,3,4 et un devrait obtenir 1 et b devrait obtenir 12

alors on peut faire comme ça
def hello(a,*args,b=1): pass hello(1, 2, 3, 4,b=12)

Quelque chose de plus :

 def hello(a,*c,b=1,**kwargs): print(b) print(c) print(a) print(kwargs) hello(1,2,1,2,8,9,c=12) 

sortie:

 1 (2, 1, 2, 8, 9) 1 {'c': 12} 

Cela peut aussi arriver dans Django si vous utilisez jquery ajax pour url qui renverse à une fonction qui ne contient pas de paramètre “request”

 $.ajax({ url: '{{ url_to_myfunc }}', }); def myfunc(foo, bar): ...