Las clases son los moldes del software, pero un molde sin acciones asociadas está vacío. En la Programación Orientada a Objetos (POO), los comportamientos y operaciones que definen lo que una estructura puede hacer se modelan a través de los métodos. Sin embargo, no todas las acciones de un sistema requieren el mismo nivel de acceso a la información. Para darnos una flexibilidad arquitectónica total, disponemos de tres tipos fundamentales de metodos en python: métodos de instancia, métodos de clase y métodos estáticos.
Muchos programadores se limitan a usar el parámetro self en todas partes sin saber que están sobrecargando la memoria o limitando la reutilización de su código. Conocer cuándo decorar un método con @classmethod o @staticmethod te permitirá diseñar APIs limpias, seguras y altamente legibles.
En este tutorial práctico vas a aprender la diferencia técnica exacta de cada método, su acceso a la memoria y cómo implementar patrones de diseño profesionales (como el patrón Factory o constructores alternativos) que te harán destacar en cualquier equipo de desarrollo.
Para abrir el apetito del código limpio, echa un vistazo al siguiente bloque «spoiler» que consolida los tres tipos de metodos en python en una única estructura perfectamente armada:
import json
class Usuario:
plataforma = "Todo Python" # Atributo de clase
def __init__(self, nombre: str, rol: str):
self.nombre = nombre # Atributo de instancia
self.rol = rol # Atributo de instancia
# 1. Método de Instancia (Usa "self")
def describir(self) -> str:
return f"Usuario: {self.nombre} - Rol: {self.rol} (en {self.plataforma})"
# 2. Método de Clase (Usa "@classmethod" y "cls")
@classmethod
def desde_json(cls, json_str: str):
# Útil como constructor alternativo (Factory Pattern)
datos = json.loads(json_str)
return cls(nombre=datos["name"], rol=datos["role"])
# 3. Método Estático (Usa "@staticmethod", sin self ni cls)
@staticmethod
def es_email_valido(email: str) -> bool:
# Utilidad lógica pura e independiente
return "@" in email and email.endswith(".com")
# Uso de los tres métodos
# A. Método estático directo desde la clase
print(Usuario.es_email_valido("admin@todopython.com")) # Salida: True
# B. Método de clase como constructor alternativo
nuevo_user = Usuario.desde_json('{"name": "Sofía", "role": "Dev"}')
# C. Método de instancia desde el objeto creado
print(nuevo_user.describir()) # Salida: Usuario: Sofía - Rol: Dev (en Todo Python)
1. Métodos de Instancia: El Estándar y el uso de «self»
Son los métodos por defecto de la programación orientada a objetos. Si defines una función dentro de una clase y no le añades ningún decorador especial, Python la considerará automáticamente un método de instancia.
Su característica fundamental es que deben recibir obligatoriamente como primer parámetro la palabra clave `self` (por convención estándar). Este parámetro representa al objeto específico sobre el que se está llamando la acción.
Los métodos de instancia tienen un control absoluto del sistema:
- Pueden leer y modificar los atributos específicos del objeto individual (a través de
self.nombre_atributo). - Pueden acceder y alterar variables compartidas a nivel de clase (a través de
self.__class__.atributoo directamente de la clase). - Pueden invocar otros métodos de instancia sobre el mismo objeto.
¿Cuándo usarlos? En el 90% de tus acciones diarias. Úsalos siempre que la lógica del método requiera conocer o alterar las variables individuales de un objeto concreto en memoria.
2. Métodos de Clase (@classmethod): Constructores Alternativos y «cls»
Para definir un método de clase, debes anteceder la definición con el decorador nativo @classmethod. En este caso, el método ya no interactúa con una instancia individual en la memoria RAM, sino con la clase misma como objeto global.
Por tanto, el primer argumento obligatorio ya no es self, sino cls (representando a la clase actual). Dado que no reciben self, los métodos de clase no pueden acceder a los atributos individuales de las instancias.
El Caso de Uso Estrella: El Patrón Factory
El uso más común y profesional de los métodos de clase es servir como constructores alternativos (Factory Pattern). Imagina que tu clase tiene un inicializador normal __init__ que recibe nombre y edad. Pero a menudo necesitas instanciar usuarios a partir de una tupla de base de datos o de un archivo CSV. En lugar de ensuciar tu código con validaciones previas, creas métodos de clase limpios y descriptivos:
class Perfil:
def __init__(self, nombre: str, edad: int):
self.nombre = nombre
self.edad = edad
# Constructor alternativo a partir de una tupla
@classmethod
def desde_tupla(cls, datos_tupla: tuple):
nombre, edad = datos_tupla
# cls(...) equivale a llamar a Perfil(...) de forma dinámica
return cls(nombre, edad)
# Instanciación normal
perfil1 = Perfil("Sofía", 26)
# Instanciación alternativa limpia y legible
datos_db = ("Alejandro", 32)
perfil2 = Perfil.desde_tupla(datos_db)
print(perfil2.nombre) # Salida: Alejandro
Usar cls en lugar del nombre estático de la clase (como Perfil) es una excelente práctica de diseño, ya que asegura que si la clase se hereda en el futuro, el constructor alternativo creará instancias de la clase hija de forma automática y transparente.
3. Métodos Estáticos (@staticmethod): Utilidades e Independencia
Se definen utilizando el decorador @staticmethod. Estos métodos son la opción más independiente de la POO en Python: no reciben de forma automática ningún primer parámetro especial (ni self ni cls).
Básicamente, un método estático es una función normal y corriente, pero que decidimos colocar dentro del namespace (ámbito) de una clase por pura cohesión de diseño y organización de código.
Dado que no tienen acceso ni al estado de la instancia ni al de la clase, son ideales para albergar funciones de utilidad puras que procesan los argumentos de entrada y devuelven un resultado sin alterar ningún estado externo (funciones puras):
class Conversor:
factores = {"celsius_a_fahrenheit": 1.8}
@staticmethod
def celsius_a_fahrenheit(celsius: float) -> float:
# No accedemos a "self" ni a "cls", es un cálculo puro e independiente
return (celsius * 1.8) + 32
# Se puede llamar directamente sin crear un objeto
temperatura = Conversor.celsius_a_fahrenheit(25.0)
print(temperatura) # Salida: 77.0
¿Por qué meterlo en la clase si podríamos tenerlo fuera? Por orden y limpieza. Ayuda a que otros desarrolladores entiendan que ese método de conversión está lógicamente relacionado con el concepto de Conversor, evitando llenar tus módulos de funciones sueltas.
4. Tabla Comparativa Definitiva: ¿Cuál elegir?
En esta tabla resumimos los principales factores y diferencias técnicas que debes evaluar antes de definir cualquiera de tus metodos en python:
| Tipo de Método | Decorador | Parámetro Clave | Acceso a Estados | Caso de Uso Ideal |
|---|---|---|---|---|
| Instancia | Ninguno | self | Instancia y Clase (Lectura/Escritura) | Acciones típicas del objeto que leen o mutan sus variables. |
| Clase | @classmethod | cls | Solo Clase (Lectura/Escritura) | Constructores alternativos (Factory Pattern) o configuración global. |
| Estático | @staticmethod | Ninguno | Ninguno (Independiente) | Funciones auxiliares, validadores lógicos o cálculos matemáticos puros. |
Conclusión y Siguientes Pasos
Comprender las diferencias entre los métodos de instancia, los de clase (`@classmethod`) y los estáticos (`@staticmethod`) te dotará de un criterio de diseño de nivel senior para estructurar tus bases de código en Python de forma robusta y altamente eficiente en memoria. Para asentar estas buenas prácticas, recuerda seguir siempre estas tres reglas esenciales: usa métodos de instancia exclusivamente cuando necesites acceder o mutar el estado individual del objeto, sácale partido a `@classmethod` como constructor alternativo para mantener limpio tu inicializador, y recurre a `@staticmethod` únicamente para utilidades puras asociadas lógicamente a la clase. Te recomendamos consultar el apartado de la documentación oficial sobre las clases y métodos en Python y experimentar implementando constructores alternativos en tus proyectos. ¡En el siguiente paso de nuestro Roadmap nos adentraremos en el fascinante mundo de los métodos especiales o Dunder Methods (`__str__`, `__repr__`) para dotar de superpoderes a tus objetos!

