TypeError: otrzymano wiele wartości argumentu

162

Czytałem inne wątki, które miały związek z tym błędem i wydaje mi się, że mój problem ma interesującą wyraźną różnicę niż wszystkie posty, które przeczytałem do tej pory, a mianowicie wszystkie inne posty do tej pory zawierają błąd dotyczący albo utworzonego przez użytkownika klasa lub wbudowany zasób systemowy. Mam ten problem podczas wywoływania funkcji, nie mogę dowiedzieć się, do czego to może służyć. Jakieś pomysły?

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)

Komunikat o błędzie:

    Horizontol_drawbox(BOX_LENGTH, fillBox = True)
TypeError: Horizontol_drawbox() got multiple values for argument 'fillBox'
chopper remis lion4
źródło
5
Jaka jest deklaracja Horizontol_drawboxfunkcji? Jeśli zaczyna się od fillBox, to jest to błąd (przypisywany raz argumentem pozycyjnym, a drugi argumentowi słowem kluczowemu).
Cilyan,

Odpowiedzi:

243

Dzieje się tak, gdy określono argument słowa kluczowego, który zastępuje argument pozycyjny. Na przykład wyobraźmy sobie funkcję, która rysuje kolorowe pudełko. Funkcja wybiera kolor, który ma być użyty i deleguje rysowanie ramki do innej funkcji, przekazując wszystkie dodatkowe argumenty.

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

Potem wezwanie

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

zakończy się niepowodzeniem, ponieważ dwie wartości są przypisane color: "blellow"jako pozycyjna i "green"jako słowo kluczowe. ( painter.draw_boxma zaakceptować argumenty heighti width).

Łatwo to zobaczyć na przykładzie, ale oczywiście jeśli pomieszamy argumenty podczas rozmowy, debugowanie może nie być łatwe:

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

Tutaj colorjest przypisany 20, potem args=[30]i colorponownie przypisany "green".

Cilyan
źródło
Ciekawe - kiedy trafiłem na ten błąd, też chodziło o colorkłótnię. Problem był nieco inny - mój model_matrixargument stał się tylko słowem kluczowym, a jakiś starszy kod przekazywał go jako argument pozycyjny. Nowe API oczekiwało colori zamiast tego otrzymało macierz 4x4.
Tomasz Gandor
Cześć, nie rozumiem tego w drugim przykładzie. To również spełnia warunek: When a keyword argument is specified that overwrites a positional argument. Ale dlaczego ten drugi może działać? Jaka jest zasada, gdy Python przypisuje argumenty. Dziękuję Ci.
Alston,
2
@Stallman: drugi podany przeze mnie przykład również nie działa. color = 20 jest w konflikcie z color = „green”. Reguła przypisania jest podana zaraz po. Więcej informacji: docs.python.org/3/tutorial/controlflow.html#keyword-arguments W szczególności trzeci z 4 przykładów „nieprawidłowych wywołań”.
Cilyan
Dostałem ten błąd, gdy robiłam: dict(**{'a': 1}, **{'a': 2}). Działa to dobrze, jeśli nie powtórzyć nazwy param: dict(**{'a': 1}, **{'b': 2}).
Robo Robok
@RoboRobok rzeczywiście, jest to "nowy sposób" (3.5) na uzyskanie błędu i jest opisany w python.org/dev/peps/pep-0448/#specification Sugeruję dodanie własnej odpowiedzi na pytanie, aby to zrobić następnym odwiedzającym łatwiej będzie znaleźć Twoją sugestię.
Cilyan
82

Miałem ten sam problem, który jest naprawdę łatwy do rozwiązania, ale jego przejrzenie zajęło mi trochę czasu.

Skopiowałem deklarację do miejsca, w którym ją stosowałem i zostawiłem tam argument „siebie”, ale uświadomienie sobie tego zajęło mi wieki.

miałem

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

ale tak powinno być

self.myFunction(a, b, c='123')
Q --- dziesięć
źródło
1
Lub zastąp najpierw selfnazwą klasy. ;)
Tomasz Gandor
Fantastyczna odpowiedź. To jest dokładnie problem, z którym się spotkałem. Dzięki, Q!
ramhiser
55

Dzieje się tak również, jeśli zapomnisz selfdeklaracji wewnątrz metod klas.

Przykład:

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

Nie można tego nazwać jak self.is_overlapping(x1=2, x2=4, y1=3, y2=5) z:

{TypeError} is_overlapping () pobrał wiele wartości dla argumentu „x1”

PRACE :

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
źródło
1
Ten komentarz pomaga mi dostrzec mój problem: zapomniałem dodać selfargument w deklaracji funkcji. czyli co powinno być def myFunction(self, a, b, c='123')napisane jako def myFunction(a, b, c='123'). A ponieważ bpobiera listę i cprzyjmuje wartość skalarną, gdy brakuje self, argumenty się pomieszały i ostatecznie dane wejściowe btrafiają do c, powodując błąd „wiele argumentów”. Popełniam ten błąd, ponieważ przetestowałem tę wewnętrzną metodę poza klasą i zapomniałem dodać z selfpowrotem. Mam nadzieję, że pomoże to komuś innemu!
yuqli
@yuqli Właśnie w ten sposób również wchodzę w ten problem. ;) Miło słyszeć, że ten post Ci pomógł.
gies0r
1
zaoszczędziło mi też sporo czasu :)
nexla
Działa również po udekorowaniu funkcji, @staticmethodktóra może być lepszym podejściem, gdy selfnie jest z natury wymagana.
ayorgo
25

Mój problem był podobny do Q --- dziesięć, ale w moim przypadku było to, że zapomniałem podać argument własny do funkcji klasy:

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

Powinno stać się

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

Ta wadliwa implementacja jest trudna do zauważenia podczas wywoływania metody klasy jako:

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

Co da TypeError: got multiple values for argument. Miejmy nadzieję, że pozostałe odpowiedzi są wystarczająco jasne, aby każdy mógł szybko zrozumieć i naprawić błąd. Jeśli nie, miej nadzieję, że ta odpowiedź ci pomoże!

Andreas Forslöw
źródło
3
o
rany
3

Po prostu nie możesz zrobić następujących rzeczy:

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

Ponieważ zmienną „y” przekazujesz do funkcji dwukrotnie: raz jako kwargi i raz jako deklarację funkcji.

quasipolynomial
źródło
2

Przyprowadzono mnie tutaj z powodu, który nie został wyraźnie wymieniony w odpowiedziach do tej pory, aby zaoszczędzić innym kłopotu:

Błąd występuje również wtedy, gdy argumenty funkcji zmieniły kolejność - z tego samego powodu, co w akceptowanej odpowiedzi: argumenty pozycyjne kolidują z argumentami słów kluczowych.

W moim przypadku było tak, ponieważ kolejność argumentów set_axisfunkcji Pandas zmieniła się między 0,20 a 0,22:

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

Korzystanie z często spotykanych przykładów set_axis skutkuje tym mylącym błędem, ponieważ gdy dzwonisz:

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

przed 0.22, ['a', 'b', 'c']jest przypisany do osi, ponieważ jest to pierwszy argument, a następnie argument pozycyjny dostarcza „wiele wartości”.

Heath Raftery
źródło
1

Ten wyjątek również zostanie zgłoszony za każdym razem, gdy funkcja została wywołana za pomocą kombinacji keyword argumentsi args,kwargs

Przykład:

def function(a, b, c, *args, **kwargs):
    print(f"a: {a}, b: {b}, c: {c}, args: {args}, kwargs: {kwargs}")

function(a=1, b=2, c=3, *(4,))

I wzrośnie:

TypeError                                 Traceback (most recent call last)
<ipython-input-4-1dcb84605fe5> in <module>
----> 1 function(a=1, b=2, c=3, *(4,))

TypeError: function() got multiple values for argument 'a'

A także stanie się to bardziej skomplikowane, gdy użyjesz go niewłaściwie w dziedzictwie . więc uważaj na te rzeczy!

1- Wywołanie funkcji za pomocą keyword argumentsi args:

class A:
    def __init__(self, a, b, *args, **kwargs):
        self.a = a
        self.b = b
    
class B(A):
    def __init__(self, *args, **kwargs):

        a = 1
        b = 2
        super(B, self).__init__(a=a, b=b, *args, **kwargs)

B(3, c=2)

Wyjątek:

TypeError                                 Traceback (most recent call last)
<ipython-input-5-17e0c66a5a95> in <module>
     11         super(B, self).__init__(a=a, b=b, *args, **kwargs)
     12 
---> 13 B(3, c=2)

<ipython-input-5-17e0c66a5a95> in __init__(self, *args, **kwargs)
      9         a = 1
     10         b = 2
---> 11         super(B, self).__init__(a=a, b=b, *args, **kwargs)
     12 
     13 B(3, c=2)

TypeError: __init__() got multiple values for argument 'a'

2- Wywołanie funkcji z keyword argumentsi kwargsktóra zawiera słowa kluczowe argumenty za:

class A:
    def __init__(self, a, b, *args, **kwargs):
        self.a = a
        self.b = b
    
class B(A):
    def __init__(self, *args, **kwargs):

        a = 1
        b = 2
        super(B, self).__init__(a=a, b=b, *args, **kwargs)

B(**{'a': 2})

Wyjątek:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-c465f5581810> in <module>
     11         super(B, self).__init__(a=a, b=b, *args, **kwargs)
     12 
---> 13 B(**{'a': 2})

<ipython-input-7-c465f5581810> in __init__(self, *args, **kwargs)
      9         a = 1
     10         b = 2
---> 11         super(B, self).__init__(a=a, b=b, *args, **kwargs)
     12 
     13 B(**{'a': 2})

TypeError: __init__() got multiple values for keyword argument 'a'
Neo
źródło