"TypeError: método() toma 1 argumento posicional pero se dieron 2" pero solo pasé uno

Resuelto Zero Piraeus asked hace 10 años • 12 respuestas

Si tengo una clase...

class MyClass:

    def method(arg):
        print(arg)

... que uso para crear un objeto...

my_object = MyClass()

... a lo que llamo method("foo")así ...

>>> my_object.method("foo")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: method() takes exactly 1 positional argument (2 given)

... ¿por qué Python me dice que le di dos argumentos, cuando solo le di uno?

Zero Piraeus avatar May 30 '14 06:05 Zero Piraeus
Aceptado

En Python, esto:

my_object.method("foo")

... es azúcar sintáctico , que el intérprete traduce entre bastidores en:

MyClass.method(my_object, "foo")

... que, como puede ver, efectivamente tiene dos argumentos, solo que el primero está implícito, desde el punto de vista de la persona que llama.

Esto se debe a que la mayoría de los métodos funcionan con el objeto al que se les llama, por lo que debe haber alguna forma de hacer referencia a ese objeto dentro del método. Por convención, este primer argumento se llama selfdentro de la definición del método:

class MyNewClass:

    def method(self, arg):
        print(self)
        print(arg)

Si llama method("foo")a una instancia de MyNewClass, funciona como se esperaba:

>>> my_new_object = MyNewClass()
>>> my_new_object.method("foo")
<__main__.MyNewClass object at 0x29045d0>
foo

De vez en cuando (pero no a menudo), realmente no te importa el objeto al que está vinculado tu método, y en esa circunstancia, puedes decorar el método con la staticmethod()función incorporada para decirlo:

class MyOtherClass:

    @staticmethod
    def method(arg):
        print(arg)

... en cuyo caso no es necesario agregar un selfargumento a la definición del método, y aún funciona:

>>> my_other_object = MyOtherClass()
>>> my_other_object.method("foo")
foo
Zero Piraeus avatar May 29 '2014 23:05 Zero Piraeus

En palabras simples

En Python debes agregar selfcomo primer parámetro a todos los métodos definidos en las clases:

class MyClass:
  def method(self, arg):
    print(arg)

Entonces puedes utilizar tu método según tu intuición:

>>> my_object = MyClass()
>>> my_object.method("foo")
foo

Para una mejor comprensión, también puedes leer las respuestas a esta pregunta: ¿ Cuál es el propósito de uno mismo?

simhumileco avatar Jun 19 '2019 09:06 simhumileco