Regístrate para acceder a más de 15 cursos gratuitos de programación con un simulador

Sobrescritura de métodos Python: Profundizando en las clases

A veces necesitamos ajustar el comportamiento de una clase existente sin modificar su código original, como cuando proviene de una biblioteca externa o ya se usa en muchos lugares. Para hacer esto sin duplicar código, vamos a aprender sobre una herramienta clave en la Programación Orientada a Objetos: sobrescribir un método.


¿Qué es reescribir (sobrescribir) un método?

Imagina que un método es como una receta que está en una clase. Cuando creamos una nueva clase basada en esa (lo que llamamos una subclase), podemos tomar esa receta y cambiarle algunas instrucciones. Eso es sobrescribir un método: decir “cuando se llame a este método en mi subclase, quiero que se haga algo distinto, o que se haga algo más”.


Caso práctico: HTMLSelectElement

Tenemos una clase llamada HTMLSelectElement que representa un menú con varias opciones, como los que usamos en HTML (una etiqueta <select>).

Veamos cómo se ve esta clase en Python:

class HTMLSelectElement:
    def __init__(self, options):
        self.options = options

    def item(self, index):
        return self.options[index]

Este código define:

  • Una propiedad options que es una lista de opciones.
  • Un método item() que recibe un número (índice) y devuelve la opción correspondiente de la lista.

Probemos cómo funciona:

select = HTMLSelectElement(["Opción 1", "Opción 2", "Opción 3"])
print(select.item(1))  # Muestra: Opción 2

Todo bien hasta aquí. Pero... ¿qué pasa si intentamos acceder a un índice que no existe?

print(select.item(5))  # Error: IndexError

Eso lanza una excepción y, si no la controlamos, puede hacer que el programa se detenga.


Reescribir el método para manejar errores

Queremos mejorar esa función item(current_index) para que verifique si el índice es válido y, si no lo es, devuelva un mensaje amigable. Para eso, vamos a crear una subclase que extienda la clase original y sobrescriba el método item():

class HTMLCustomSelectElement(HTMLSelectElement):
    def item(self, index):
        if index < 0 or index >= len(self.options):
            return "Error: índice fuera de rango"
        return super().item(index)

Aquí está pasando algo interesante:

  • Creamos una subclase llamada HTMLCustomSelectElement.
  • En ese nuevo método item(index):
    • Primero verificamos si el índice está dentro del rango válido.
    • Si es válido, llamamos al método original de la clase padre con super().item(index).

Probaremos cómo funciona:

custom_select = HTMLCustomSelectElement(["Uno", "Dos", "Tres"])
print(custom_select.item(1))  # "Dos"
print(custom_select.item(5))  # "Error: índice fuera de rango"

¡Listo! Ahora el programa ya no lanza errores inesperados, y le da al usuario una respuesta clara.


¿Por qué usamos super()?

Imagina que en lugar de esto hiciéramos:

def item(self, index):
    return self.item(index)
¿Qué pasaría? Este código se llama a sí mismo una y otra vez sin fin, y eso es un problema llamado recursión infinita, que termina en un error. Cuando usamos self, estamos llamando al método actual, no al de la clase padre.

Por eso usamos super(): para decirle explícitamente a Python que ejecute la versión anterior del método desde la clase padre.


Lo que no se puede hacer al sobrescribir

Cuando se sobrescribe un método:

  • Hay que usar el mismo nombre del método.
  • Los argumentos deben coincidir (mismo número y tipo esperados).

Además, hay algo importante sobre cómo se comportan los objetos:

select = HTMLCustomSelectElement(["A", "B"])
select.item(1)  # Siempre usa el método de HTMLCustomSelectElement

Desde fuera del objeto, no se puede forzar que se use el método original (HTMLSelectElement.item()), porque el objeto ya fue creado como instancia de la subclase.


Cuidado al usar subclases

Crear una subclase y empezar a usarla suena sencillo cuando tú controlas todo el código. Pero a veces el código que crea los objetos está en otra parte, como una biblioteca externa, o algo que no puedes modificar.

Por ejemplo:

element = HTMLSelectElement(["X", "Y"])
otro = html.query_selector('select')  # Función externa que devuelve una instancia

En ese caso, aunque tú creaste una subclase que mejora el comportamiento, no puedes hacer que query_selector() use tu nueva clase, porque no tienes control sobre cómo se crean esos objetos.

¿Y se puede convertir el objeto al nuevo tipo? Técnicamente podrías, pero en la práctica puede ser complicado y poco recomendable.


Alternativas: ¿si no puedo sobrescribir?

Alternativa Ventajas
Composición de clases Puedes incluir un objeto como atributo
Patrón decorador Permite extender funcionalidades sin heredar
Paso explícito de clases Solo funciona si tú controlas el código base

Resumen

  • Sobrescribir (reescribir) métodos es útil para cambiar o ampliar el comportamiento de una clase sin modificar su código original.
  • Se hace creando una subclase y escribiendo un método con el mismo nombre y parámetros.
  • Para acceder al comportamiento original desde la subclase, usamos super().
  • Si se llama al método sobrescrito usando self, se corre el riesgo de entrar en recursión infinita.
  • Desde fuera del objeto, no se puede forzar el uso de la versión anterior del método.

Para acceder completo a curso necesitas un plan básico

El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.

Obtener acceso
130
cursos
1000
ejercicios
2000+
horas de teoría
3200
test

Obtén acceso

Cursos de programación para principiantes y desarrolladores experimentados. Comienza tu aprendizaje de forma gratuita

  • 130 cursos, 2000+ horas de teoría
  • 1000 ejercicios prácticos en el navegador
  • 360 000 estudiantes
Al enviar el formulario, aceptas el «Política de privacidad» y los términos de la «Oferta», y también aceptas los «Términos y condiciones de uso»

Nuestros graduados trabajan en empresas como:

Bookmate
Health Samurai
Dualboot
ABBYY