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.