TypeError: a obtenu plusieurs valeurs pour l'argument

143

J'ai lu les autres discussions qui avaient à voir avec cette erreur et il semble que mon problème présente une différence distincte intéressante par rapport à tous les messages que j'ai lus jusqu'à présent, à savoir, tous les autres messages jusqu'à présent ont l'erreur en ce qui concerne soit un utilisateur créé classe ou une ressource système intégrée. Je rencontre ce problème lors de l'appel d'une fonction, je n'arrive pas à comprendre à quoi cela pourrait servir. Des idées?

BOX_LENGTH = 100
turtle.speed(0)
fill = 0
for i in range(8):
    fill += 1
    if fill % 2 == 0:
        Horizontol_drawbox(BOX_LENGTH, fillBox = False)
    else:
        Horizontol_drawbox(BOX_LENGTH, fillBox = True)

    for i in range(8):
        fill += 1
        if fill % 2 == 0:
            Vertical_drawbox(BOX_LENGTH,fillBox = False)
        else:
            Vertical_drawbox(BOX_LENGTH,fillBox = True)

Message d'erreur:

    Horizontol_drawbox(BOX_LENGTH, fillBox = True)
TypeError: Horizontol_drawbox() got multiple values for argument 'fillBox'
chopper dessiner lion4
la source
5
Quelle est la déclaration de la Horizontol_drawboxfonction? Si cela commence par fillBox, alors c'est la faute (assignée une fois avec l'argument positionnel et une deuxième fois avec l'argument mot-clé).
Cilyan

Réponses:

223

Cela se produit lorsqu'un argument de mot-clé est spécifié qui écrase un argument de position. Par exemple, imaginons une fonction qui dessine une boîte colorée. La fonction sélectionne la couleur à utiliser et délègue le dessin de la boîte à une autre fonction, en relayant tous les arguments supplémentaires.

def color_box(color, *args, **kwargs):
    painter.select_color(color)
    painter.draw_box(*args, **kwargs)

Puis l'appel

color_box("blellow", color="green", height=20, width=30)

échouera car deux valeurs sont attribuées à color: "blellow"comme positionnel et "green"comme mot-clé. ( painter.draw_boxest censé accepter les arguments heightet width).

C'est facile à voir dans l'exemple, mais bien sûr, si l'on mélange les arguments à l'appel, il peut ne pas être facile de déboguer:

# misplaced height and width
color_box(20, 30, color="green")

Ici, colorest affecté 20, alors args=[30]et colorest de nouveau attribué "green".

Cilyan
la source
Intéressant - lorsque j'ai rencontré cette erreur, il s'agissait également d'un colorargument. Le problème était un peu différent - mon model_matrixargument est devenu un mot clé uniquement, et certains codes hérités l'ont fait passer comme argument de position. La nouvelle API attendait coloret a obtenu une matrice 4x4 à la place.
Tomasz Gandor
Salut, je ne comprends pas pour le deuxième exemple. Il a également satisfait à la condition: When a keyword argument is specified that overwrites a positional argument. Mais pourquoi ce dernier peut-il fonctionner? Quelle est la règle lorsque python attribue les arguments. Je vous remercie.
Alston
2
@Stallman: le deuxième exemple que j'ai donné est également un exemple qui ne fonctionne pas. color = 20 conflits avec color = "green". La règle d'attribution est donnée juste après. Plus d'infos: docs.python.org/3/tutorial/controlflow.html#keyword-arguments En particulier le 3ème des 4 exemples "d'appels non valides".
Cilyan
70

J'ai eu le même problème qui est vraiment facile à résoudre, mais il m'a fallu un certain temps pour le résoudre.

J'avais copié la déclaration là où je l'utilisais et j'avais laissé là l'argument du «moi», mais il m'a fallu des siècles pour m'en rendre compte.

j'ai eu

self.myFunction(self, a, b, c='123')

mais ça aurait dû être

self.myFunction(a, b, c='123')
Q --- dix
la source
1
Ou remplacez d'abord selfpar le nom de la classe. ;)
Tomasz Gandor
49

Cela se produit également si vous oubliez la selfdéclaration dans les méthodes de classe.

Exemple:

class Example():
    def is_overlapping(x1, x2, y1, y2):
        # Thanks to https://stackoverflow.com/a/12888920/940592
        return max(x1, y1) <= min(x2, y2)

Ne l' appelle pas comme self.is_overlapping(x1=2, x2=4, y1=3, y2=5) avec:

{TypeError} is_overlapping () a obtenu plusieurs valeurs pour l'argument 'x1'

TRAVAUX :

class Example():
    def is_overlapping(self, x1, x2, y1, y2):
        # Thanks to https://stackoverflow.com/a/12888920/940592
        return max(x1, y1) <= min(x2, y2)
gies0r
la source
Ce commentaire m'aide à repérer mon problème: j'oublie d'ajouter un selfargument à l'intérieur de la déclaration de fonction. c'est-à-dire que ce qui devrait être def myFunction(self, a, b, c='123')était écrit comme def myFunction(a, b, c='123'). Et parce que bprend une liste et cprend un scalaire, quand il manque self, les arguments sont foirés et finalement l'entrée de bva à c, provoquant l'erreur "arguments multiples". Je fais cette erreur parce que j'ai testé cette méthode interne en dehors de la classe et j'ai oublié d'ajouter le selfback in. J'espère utile pour quelqu'un d'autre!
yuqli
@yuqli C'est exactement comme ça que j'entre aussi dans ce problème. ;) Ravi d'entendre que ce message vous a aidé.
gies0r
1
m'a aussi sauvé du temps :)
nexla
Fonctionne également après avoir décoré la fonction @staticmethodqui peut être une meilleure approche lorsqu'elle selfn'est pas intrinsèquement requise.
ayorgo
22

Mon problème était similaire à celui de Q --- dix, mais dans mon cas, c'était que j'avais oublié de fournir l'argument self à une fonction de classe:

class A:
    def fn(a, b, c=True):
        pass

Devrait devenir

class A:
    def fn(self, a, b, c=True):
        pass

Cette implémentation défectueuse est difficile à voir lors de l'appel de la méthode de classe comme suit:

a_obj = A()
a.fn(a_val, b_val, c=False)

Ce qui donnera un TypeError: got multiple values for argument. Espérons que le reste des réponses ici soit suffisamment clair pour que quiconque puisse comprendre et corriger rapidement l'erreur. Sinon, espérons que cette réponse vous aidera!

Andreas Forslöw
la source
2
oh mec, oublier "moi" était aussi mon problème, quelle exception trompeuse à
lever
3

En termes simples, vous ne pouvez pas effectuer les opérations suivantes:

class C(object):
    def x(self, y, **kwargs):
        # Which y to use, kwargs or declaration? 
        pass

c = C()
y = "Arbitrary value"
kwargs["y"] = "Arbitrary value"
c.x(y, **kwargs) # FAILS

Parce que vous passez la variable «y» dans la fonction deux fois: une fois comme kwargs et une fois comme déclaration de fonction.

quasi-polynomial
la source
2

J'ai été amené ici pour une raison qui n'a pas été explicitement mentionnée dans les réponses jusqu'à présent, afin d'éviter aux autres le problème:

L'erreur se produit également si les arguments de la fonction ont changé d'ordre - pour la même raison que dans la réponse acceptée: les arguments de position entrent en conflit avec les arguments de mot-clé.

Dans mon cas, c'était parce que l'ordre des arguments de la set_axisfonction Pandas a changé entre 0,20 et 0,22:

0.20: DataFrame.set_axis(axis, labels)
0.22: DataFrame.set_axis(labels, axis=0, inplace=None)

L'utilisation des exemples couramment trouvés pour set_axis entraîne cette erreur déroutante, car lorsque vous appelez:

df.set_axis(['a', 'b', 'c'], axis=1)

avant 0.22, ['a', 'b', 'c']est assigné à l'axe car c'est le premier argument, puis l'argument positionnel fournit "plusieurs valeurs".

Heath Raftery
la source