146 votes

La méthode de classe génère "TypeError: ... a reçu plusieurs valeurs pour l'argument de mot-clé ..."

Si je définis une méthode de classe avec un argument de mot-clé de la manière suivante :

class foo(object):
  def foodo(chose=None, string='pas sous-vêtements'):
    print chose if chose else "rien" 
    print 'un string est', string

appeler la méthode génère une TypeError :

myfoo = foo()
myfoo.foodo(chose="quelque chose")

...
TypeError: foodo() a reçu des valeurs multiples pour l'argument de mot-clé 'chose'

Que se passe-t-il?

175voto

drevicko Points 1073

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

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

elle 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 les 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'assigner "something" à thing, d'où l'exception.

Pour le démontrer, essayez d'exécuter ceci avec le code original :

myfoo.foodo("something")
print
print myfoo

Vous obtiendrez :

<__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 de l'instance 'myfoo' de la classe 'foo'. Cette section de la documentation explique un peu plus comment fonctionnent les arguments de fonction.

52voto

joe_doe Points 521

Merci pour les posts instructifs. J'aimerais juste noter que si vous obtenez l'erreur "TypeError: foodo() got multiple values for keyword argument 'thing'", cela peut aussi être parce que vous passez accidentellement le 'self' en tant que paramètre lors de l'appel de la fonction (probablement parce que vous avez copié la ligne de la déclaration de la classe - c'est une erreur commune quand on est pressé).

30voto

woot Points 2407

Cela peut sembler évident, mais cela peut aider quelqu'un qui ne l'a jamais vu auparavant. Cela arrive également pour les fonctions normales si vous assignez par erreur un paramètre par position et explicitement par nom.

>>> def foodo(chose=None, ficelle='pas de sous-vêtements'):
...     print chose if chose else "rien"
...     print 'une ficelle est', ficelle
...
>>> foodo('quelque chose', chose='tout')
Erreur de syntaxe : foodo() a reçu plusieurs valeurs pour l'argument de mot-clé 'chose'

8voto

user1743931 Points 41

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

>>> 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' présent dans kwargs.

Vous devriez retirer l'argument clé des kwargs avant de le passer à la méthode.

6voto

adi gunawan Points 77

Il suffit d'ajouter le décorateur 'staticmethod' à la fonction et le problème est résolu

class foo(object):
    @staticmethod
    def foodo(thing=None, thong='pas sous-vêtements'):
        print thing if thing else "rien" 
        print 'un string est',thong

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