TypeError: obtuvo múltiples valores para el argumento

143

Leí los otros hilos que tenían que ver con este error y parece que mi problema tiene una diferencia distinta interesante que todas las publicaciones que he leído hasta ahora, es decir, todas las otras publicaciones hasta ahora tienen el error con respecto a un usuario creado clase o un recurso del sistema integrado. Estoy experimentando este problema al llamar a una función, no puedo entender para qué podría ser. ¿Algunas ideas?

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)

Mensaje de error:

    Horizontol_drawbox(BOX_LENGTH, fillBox = True)
TypeError: Horizontol_drawbox() got multiple values for argument 'fillBox'
chopper draw lion4
fuente
55
¿Cuál es la declaración de la Horizontol_drawboxfunción? Si comienza con fillBox, entonces ese es el error (asignado una vez con argumento posicional y una segunda vez con argumento de palabra clave).
Cilyan

Respuestas:

223

Esto sucede cuando se especifica un argumento de palabra clave que sobrescribe un argumento posicional. Por ejemplo, imaginemos una función que dibuja un cuadro de color. La función selecciona el color que se utilizará y delega el dibujo del cuadro a otra función, retransmitiendo todos los argumentos adicionales.

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

Entonces la llamada

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

fallará porque se asignan dos valores a color: "blellow"como posicional y "green"como palabra clave. ( painter.draw_boxse supone que acepta los argumentos heighty width).

Esto es fácil de ver en el ejemplo, pero, por supuesto, si uno mezcla los argumentos en la llamada, puede que no sea fácil de depurar:

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

Aquí, colorse le asigna 20, luego args=[30]y colornuevamente se le asigna "green".

Cilyan
fuente
Interesante: cuando llegué a este error, también se trataba de una colordiscusión. El problema era un poco diferente: mi model_matrixargumento se convirtió solo en palabras clave, y algunos códigos heredados lo pasaron como un argumento posicional. La nueva API esperaba color, y en su lugar obtuvo una matriz 4x4.
Tomasz Gandor
Hola, no lo entiendo para el segundo ejemplo. También satisface la condición: When a keyword argument is specified that overwrites a positional argument. ¿Pero por qué este último puede funcionar? ¿Cuál es la regla cuando python asigna los argumentos? Gracias.
Alston
2
@Stallman: el segundo ejemplo que di también no funciona. color = 20 entra en conflicto con color = "verde". La regla para la asignación se da justo después. Más información: docs.python.org/3/tutorial/controlflow.html#keyword-arguments Particularmente el tercero de los 4 ejemplos de "llamadas no válidas".
Cilyan
70

Tuve el mismo problema que es realmente fácil de resolver, pero me llevó un tiempo resolverlo.

Había copiado la declaración en el lugar donde la estaba usando y había dejado allí el argumento del "yo", pero me llevó años darme cuenta de eso.

yo tenía

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

pero debería haber sido

self.myFunction(a, b, c='123')
Q --- diez
fuente
1
O reemplace primero selfcon el nombre de la clase. ;)
Tomasz Gandor
49

Esto también sucede si olvida la selfdeclaración dentro de los métodos de clase.

Ejemplo:

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

No se puede llamar así self.is_overlapping(x1=2, x2=4, y1=3, y2=5) con:

{TypeError} is_overlapping () tiene varios valores para el argumento 'x1'

OBRAS :

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
fuente
Este comentario me ayuda a detectar mi problema: olvido agregar un selfargumento dentro de la declaración de función. es decir, lo que debería estar def myFunction(self, a, b, c='123')escrito como def myFunction(a, b, c='123'). Y debido a que btoma una lista y ctoma un escalar, cuando se pierde uno mismo, los argumentos se equivocan y, finalmente, la entrada de bva a c, causando el error de "argumentos múltiples". Cometo este error porque probé este método interno fuera de la clase y olvido agregarlo selfnuevamente. ¡Espero que sea útil para alguien más!
yuqli
@yuqli Así es exactamente como me meto en este problema también. ;) Me alegra saber que esta publicación te ayudó.
gies0r
1
también me ahorró bastante tiempo :)
nexla
También funciona después de decorar la función con la @staticmethodque puede ser un mejor enfoque cuando selfno se requiere inherentemente.
ayorgo
21

Mi problema era similar a Q --- ten, pero en mi caso fue que me había olvidado de proporcionar el argumento propio a una función de clase:

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

Debe convertirse

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

Esta implementación defectuosa es difícil de ver cuando se llama al método de clase como:

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

Lo que rendirá a TypeError: got multiple values for argument. Con suerte, el resto de las respuestas aquí son lo suficientemente claras como para que cualquiera pueda comprender y corregir el error rápidamente. Si no, ¡espero que esta respuesta te ayude!

Andreas Forslöw
fuente
2
oh hombre, olvidando "auto" era mi problema también, lo que es una excepción engañosa para ser lanzado
pcko1
3

En pocas palabras, no puede hacer lo siguiente:

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

Porque pasa la variable 'y' en la función dos veces: una vez como kwargs y otra como declaración de función.

cuasipolinomial
fuente
2

Me trajeron aquí por una razón no mencionada explícitamente en las respuestas hasta ahora, así que para salvar a otros el problema:

El error también ocurre si los argumentos de la función han cambiado de orden, por la misma razón que en la respuesta aceptada: los argumentos posicionales chocan con los argumentos de las palabras clave.

En mi caso fue porque el orden de los argumentos de la set_axisfunción Pandas cambió entre 0,20 y 0,22:

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

El uso de los ejemplos comúnmente encontrados para set_axis da como resultado este error confuso, ya que cuando llama:

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

anterior a 0.22, ['a', 'b', 'c']se asigna al eje porque es el primer argumento, y luego el argumento posicional proporciona "valores múltiples".

Heath Raftery
fuente