Si je définis une méthode de classe avec un argument mot-clé ainsi:
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?
python
class
python-2.7
methods
Drevicko
la source
la source
self
est préférable à l'implicitethis
.Réponses:
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:il se comporte comme prévu.
Explication:
Sans
self
comme premier paramètre, lors de l'myfoo.foodo(thing="something")
exécution, lafoodo
méthode est appelée avec des arguments(myfoo, thing="something")
. L'instancemyfoo
est alors affectée àthing
(depuisthing
le premier paramètre déclaré), mais aussi python tente d'assigner"something"
àthing
, d' où l'exception.Pour démontrer, essayez d'exécuter ceci avec le code d'origine:
Vous sortirez comme:
Vous pouvez voir que 'thing' a reçu 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.
la source
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 'self' comme paramètre 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é).
la source
@classmethod
, la solution étant d'utiliser à lasuper().function(...)
place de<parentclass>.function(cls, ...)
.Cela peut ê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 attribuez par erreur un paramètre par position et explicitement par nom.
la source
ajoutez simplement le décorateur 'staticmethod' à la fonction et le problème est résolu
la source
myfoo.foodo(thing="something")
, chose = "quelque chose" sera assigné au premier argument, plutôt qu'à l'argument self implicite.self
Je veux ajouter une autre réponse:
there is difference between parameter and argument
vous pouvez lire en détail ici Arguments et paramètres en pythonpuisque nous avons trois paramètres:
a est un 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 affectons d'abord un comme paramètre de position, ce qui signifie que nous devons fournir une valeur à l'argument de position dans son ordre de position, ici, l'ordre est important. mais nous passons l'argument 1 à la place de a dans la fonction d'appel, puis nous fournissons également une valeur à a, en le traitant comme un argument mot-clé. maintenant a deux valeurs:
l'un est la valeur de position: a = 1
la seconde est la valeur mot-clé qui est a = 12
Solution
Nous devons changer
hello(1, 2, 3, 4,a=12)
pourhello(1, 2, 3, 4,12)
que maintenant a n'obtienne qu'une seule valeur de position qui est 1 et b obtiendra la valeur 2 et le reste des valeurs obtiendra * args (paramètre de longueur variable)Information additionnelle
si nous voulons que * args obtienne 2,3,4 et a 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 :
production :
la source
Cette erreur peut également se produire si vous passez 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.
«feu» a été accepté dans l'argument «bar». Et pourtant, il y a un autre argument «bar» présent dans les kwargs.
Vous devrez supprimer l'argument mot-clé des kwargs avant de le transmettre à la méthode.
la source
Cela peut également se produire dans Django si vous utilisez jquery ajax pour une URL qui retourne à une fonction qui ne contient pas le paramètre 'request'
la source