Link Search Menu Expand Document

Métodos en Python: instancia, clase y estáticos

En otros posts hemos visto como se pueden crear métodos con def dentro de una clase, pudiendo recibir parámetros como entrada y modificar el estado (como los atributos) de la instancia. Pues bien, haciendo uso de los decoradores, es posible crear diferentes tipos de métodos:

  • Lo mĂ©todos de instancia “normales” que ya hemos visto como metodo()
  • MĂ©todos de clase usando el decorador @classmethod
  • Y mĂ©todos estáticos usando el decorador @staticmethod

En la siguiente clase tenemos un ejemplo donde definimos los tres tipos de métodos.

class Clase:
    def metodo(self):
        return 'MĂ©todo normal', self

    @classmethod
    def metododeclase(cls):
        return 'MĂ©todo de clase', cls

    @staticmethod
    def metodoestatico():
        return "Método estático"

Veamos su comportamiento en detalle uno por uno.

MĂ©todos de instancia

Los métodos de instancia son los métodos normales, de toda la vida, que hemos visto anteriormente. Reciben como parámetro de entrada self que hace referencia a la instancia que llama al método. También pueden recibir otros argumentos como entrada.

Para saber más: El uso de "self" es totalmente arbitrario. Se trata de una convención acordada por los usuarios de Python, usada para referirse a la instancia que llama al método, pero podría ser cualquier otro nombre. Lo mismo ocurre con "cls", que veremos a continuación.

class Clase:
    def metodo(self, arg1, arg2):
        return 'MĂ©todo normal', self

Y como ya sabemos, una vez creado un objeto pueden ser llamados.

mi_clase = Clase()
mi_clase.metodo("a", "b")
# ('MĂ©todo normal', <__main__.Clase at 0x10b9daa90>)

En vista a esto, los métodos de instancia:

  • Pueden acceder y modificar los atributos del objeto.
  • Pueden acceder a otros mĂ©todos.
  • Dado que desde el objeto self se puede acceder a la clase con ` self.class`, tambiĂ©n pueden modificar el estado de la clase

MĂ©todos de clase (classmethod)

A diferencia de los métodos de instancia, los métodos de clase reciben como argumento cls, que hace referencia a la clase. Por lo tanto, pueden acceder a la clase pero no a la instancia.

class Clase:
    @classmethod
    def metododeclase(cls):
        return 'MĂ©todo de clase', cls

Se pueden llamar sobre la clase.

Clase.metododeclase()
# ('MĂ©todo de clase', __main__.Clase)

Pero también se pueden llamar sobre el objeto.

mi_clase.metododeclase()
# ('MĂ©todo de clase', __main__.Clase)

Por lo tanto, los métodos de clase:

  • No pueden acceder a los atributos de la instancia.
  • Pero si pueden modificar los atributos de la clase.

Métodos estáticos (staticmethod)

Por último, los métodos estáticos se pueden definir con el decorador @staticmethod y no aceptan como parámetro ni la instancia ni la clase. Es por ello por lo que no pueden modificar el estado ni de la clase ni de la instancia. Pero por supuesto pueden aceptar parámetros de entrada.

class Clase:
    @staticmethod
    def metodoestatico():
        return "Método estático"
mi_clase = Clase()
Clase.metodoestatico()
mi_clase.metodoestatico()

# 'Método estático'
# 'Método estático'

Por lo tanto el uso de los métodos estáticos pueden resultar útil para indicar que un método no modificará el estado de la instancia ni de la clase. Es cierto que se podría hacer lo mismo con un método de instancia por ejemplo, pero a veces resulta importante indicar de alguna manera estas peculiaridades, evitando así futuros problemas y malentendidos.

En otras palabras, los métodos estáticos se podrían ver como funciones normales, con la salvedad de que van ligadas a una clase concreta.