TypeError: obteve vários valores para o argumento

143

Eu li os outros tópicos relacionados a esse erro e parece que meu problema tem uma diferença distinta interessante do que todas as postagens que li até agora, ou seja, todas as outras postagens até agora têm o erro em relação a um usuário criado classe ou um recurso interno do sistema. Estou enfrentando esse problema ao chamar uma função, não consigo descobrir para que serve. Alguma ideia?

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)

Mensagem de erro:

    Horizontol_drawbox(BOX_LENGTH, fillBox = True)
TypeError: Horizontol_drawbox() got multiple values for argument 'fillBox'
helicóptero desenhar lion4
fonte
5
Qual é a declaração da Horizontol_drawboxfunção? Se começar fillBox, então essa é a falha (atribuída uma vez com argumento posicional e uma segunda vez com argumento de palavra-chave).
Cilyan

Respostas:

223

Isso acontece quando é especificado um argumento de palavra-chave que substitui um argumento posicional. Por exemplo, vamos imaginar uma função que desenha uma caixa colorida. A função seleciona a cor a ser usada e delega o desenho da caixa para outra função, retransmitindo todos os argumentos extras.

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

Então a ligação

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

falhará porque dois valores foram atribuídos a color: "blellow"como posicional e "green"como palavra-chave. ( painter.draw_boxdeve aceitar os argumentos heighte width).

Isso é fácil de ver no exemplo, mas é claro que se alguém misturar os argumentos de chamada, pode não ser fácil depurar:

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

Aqui, coloré atribuído 20, em seguida, args=[30]e coloré novamente atribuído "green".

Cilyan
fonte
Interessante - quando acertei esse erro, também foi sobre uma colordiscussão. O problema era um pouco diferente - meu model_matrixargumento tornou-se apenas palavra-chave e algum código legado passou como argumento posicional. A nova API estava esperando colore, em vez disso, obteve uma matriz 4x4.
Tomasz Gandor
Oi, eu não entendi para o segundo exemplo. Ela também satisfaz a condição: When a keyword argument is specified that overwrites a positional argument. Mas por que o último pode funcionar? Qual é a regra quando python atribui os argumentos. Obrigado.
Alston
2
@ Stallman: o segundo exemplo que dei também é não-útil. color = 20 entra em conflito com color = "green". A regra para atribuição é dada logo após. Mais informações: docs.python.org/3/tutorial/controlflow.html#keyword-arguments Particularmente o terceiro dos quatro exemplos de "chamadas inválidas".
Cilyan
70

Eu tive o mesmo problema que é realmente fácil de resolver, mas demorei um pouco para entender.

Eu havia copiado a declaração para onde a estava usando e deixado o argumento do 'eu' lá, mas levei anos para perceber isso.

eu tinha

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

mas deveria ter sido

self.myFunction(a, b, c='123')
Q --- dez
fonte
1
Ou substitua primeiro selfpelo nome da classe. ;)
Tomasz Gandor
49

Isso também acontece se você esquecer a selfdeclaração dentro dos métodos de classe.

Exemplo:

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

Não é assim que se chama self.is_overlapping(x1=2, x2=4, y1=3, y2=5) :

{TypeError} is_overlapping () obteve vários valores para o argumento 'x1'

TRABALHOS :

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
fonte
Este comentário me ajuda a identificar o meu problema: esqueço de adicionar um selfargumento dentro da declaração da função. ou seja, o que deveria ser def myFunction(self, a, b, c='123')escrito como def myFunction(a, b, c='123'). E porque bpega uma lista e cpega um escalar, quando faltando a si mesmo, os argumentos estragam e, eventualmente, a entrada de bvai para c, causando o erro de "múltiplos argumentos". Eu cometi esse erro porque testei esse método interno fora da classe e esqueci de adicioná-lo selfnovamente. Espero que seja útil para outra pessoa!
yuqli
@yuqli É exatamente assim que eu entro nesse problema. ;) É bom saber que este post ajudou você.
gies0r
1
me salvou bastante tempo :)
nexla 19/07/19
Também funciona depois de decorar a função com a @staticmethodqual pode ser uma abordagem melhor quando selfnão é inerentemente necessária.
AYORGO
21

Meu problema era semelhante ao Q10, mas, no meu caso, havia me esquecido de fornecer o argumento próprio para uma função de classe:

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

Deve se tornar

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

É difícil ver esta implementação defeituosa ao chamar o método de classe como:

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

O que produzirá a TypeError: got multiple values for argument. Felizmente, o restante das respostas aqui são claras o suficiente para que alguém possa entender e corrigir rapidamente o erro. Caso contrário, espero que esta resposta o ajude!

Andreas Forslöw
fonte
2
oh homem, esquecendo-se "eu" era o meu problema também, o que é uma exceção enganosa para ser jogado
pcko1
3

Simplificando, você não pode fazer o seguinte:

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 você passa a variável 'y' para a função duas vezes: uma vez como kwargs e outra como declaração de função.

quasipolinomial
fonte
2

Fui trazido aqui por um motivo não mencionado explicitamente nas respostas até o momento, para salvar os outros do problema:

O erro também ocorre se os argumentos da função mudaram de ordem - pelo mesmo motivo da resposta aceita: os argumentos posicionais colidem com os argumentos da palavra-chave.

No meu caso, foi porque a ordem dos argumentos da set_axisfunção Pandas mudou entre 0,20 e 0,22:

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

O uso dos exemplos comumente encontrados para set_axis resulta nesse erro confuso, desde quando você chama:

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

anterior a 0,22, ['a', 'b', 'c']é atribuído ao eixo porque é o primeiro argumento e, em seguida, o argumento posicional fornece "valores múltiplos".

Heath Raftery
fonte