⭐ La función super en python explicada + ejemplos! -OOP

Bienvenidos a otra entrada dedicada a este maravilloso lenguaje de programación. En este caso vamos a hablar de la función super en Python 3. Siguiendo con programación orientada a objetos, como recordarás estuvimos viendo clases y herencia simple y múltiple.

📓 Abre tu cuaderno de Jupyter Notebook que creaste en la lección anterior (13-Herencia múltiple en Python) y vamos a crear un nuevo cuaderno para esta lección. Llámalo 14-Función super() en Python.

📚 Recursos externos para profundizar: Consulta la documentación oficial de Python sobre super() y la guía de herencia en Python.

⭐ Función super en Python 3

Esta función nos permite invocar y conservar un método o atributo de una clase padre (primaria) desde una clase hija (secundaria) sin tener que nombrarla explícitamente. Esto nos brinda la ventaja de poder cambiar el nombre de la clase padre (base) o hija (secundaria) cuando queramos y aún así mantener un código funcional, sencillo y mantenible.

📌 ¿Qué hace super()?
  • Permite llamar a métodos de la clase padre sin nombrarla explícitamente.
  • Facilita el mantenimiento del código (puedes cambiar nombres de clases sin romper nada).
  • Esencial en herencia múltiple para resolver el orden de llamada (MRO).

🤔 Herencia simple de clase y atributos en Python con super()

Supongamos que queremos que una clase hija o secundaria herede los atributos de clase primaria o padre. Si nosotros no recurrimos a la función super, o llamamos al constructor init especificando los atributos, deberemos reescribirlos, lo cual en una clase por ejemplo con 20 atributos sería una pérdida de tiempo enorme. Fíjate en el ejemplo de abajo:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# https://pythones.net

class Padre(object):  # Creamos la clase Padre
    def __init__(self, ojos, cejas):  # Definimos los Atributos en el constructor
        self.ojos = ojos
        self.cejas = cejas

class Hijo(Padre):  # Creamos clase hija que hereda de Padre
    def __init__(self, ojos, cejas, cara):  # Definimos los atributos en el constructor
        self.ojos = ojos  # Sobreescribimos cada atributo
        self.cejas = cejas
        self.cara = cara  # Especificamos el nuevo atributo para Hijo

Tomas = Hijo('Marrones', 'Negras', 'Larga')  # Instanciamos
print(Tomas.ojos, Tomas.cejas, Tomas.cara)  # Imprimimos los atributos del objeto
Resultado:
Marrones Negras Larga

Vaya bodrio. Esto podemos también hacerlo así, llamando al constructor de la clase padre especificándola:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# https://pythones.net

class Padre(object):  # Creamos la clase Padre
    def __init__(self, ojos, cejas):  # Definimos los Atributos
        self.ojos = ojos
        self.cejas = cejas

class Hijo(Padre):  # Creamos clase hija que hereda de Padre
    def __init__(self, ojos, cejas, cara):  # Constructor de la clase especificando atributos
        Padre.__init__(self, ojos, cejas)  # Especificamos la clase y llamamos a su constructor + Atributos
        self.cara = cara  # Especificamos el nuevo atributo para Hijo

Tomas = Hijo('Marrones', 'Negras', 'Larga')
print(Tomas.ojos, Tomas.cejas, Tomas.cara)
Resultado:
Marrones Negras Larga

O podemos hacerlo utilizando super(). De esta forma es casi el mismo código pero no necesitamos especificar la clase padre, por lo que podremos cambiarle el nombre en cualquier momento y nuestro código seguirá funcional. Fíjate:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# https://pythones.net

class Padre(object):  # Creamos la clase Padre
    def __init__(self, ojos, cejas):  # Definimos los Atributos
        self.ojos = ojos
        self.cejas = cejas

class Hijo(Padre):  # Creamos clase hija que hereda de Padre
    def __init__(self, ojos, cejas, cara):  # Constructor de la clase especificando atributos
        super().__init__(ojos, cejas)  # Solicitamos a super llamar de la clase padre esos atributos
        self.cara = cara  # Especificamos el nuevo atributo para Hijo

Tomas = Hijo('Marrones', 'Negras', 'Larga')
print(Tomas.ojos, Tomas.cejas, Tomas.cara)
Resultado:
Marrones Negras Larga

De estas últimas dos formas llamamos al Padre de la clase Hijo para no perder su código y además agregamos un atributo nuevo «cara» para la clase Hija. Recomiendo en caso de herencia simple utilizar siempre super en Python.

super en python

Además, prueba en este código cambiar el nombre Padre, por no sé… Abuelo y verás que Hijo hereda igual los atributos de la clase padre o base / primaria.

Cambiamos clase base y aún así obtenemos los atributos:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# https://pythones.net

class Abuelo(object):  # Cambiamos el nombre de la clase base
    def __init__(self, ojos, cejas):  # Definimos los Atributos
        self.ojos = ojos
        self.cejas = cejas

class Hijo(Abuelo):  # Creamos clase hija que hereda de Abuelo
    def __init__(self, ojos, cejas, cara):  # Constructor de la clase
        super().__init__(ojos, cejas)  # super() sigue funcionando aunque cambie el nombre
        self.cara = cara

Tomas = Hijo('Marrones', 'Negras', 'Larga')
print(Tomas.ojos, Tomas.cejas, Tomas.cara)
Resultado:
Marrones Negras Larga

Como ves, super() sigue funcionando aunque cambiemos el nombre de la clase base. Esa es su gran ventaja.


Llamar un método de otra clase padre con super() en Python

Veamos otro ejemplo, en este caso heredando de list un método.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# https://pythones.net

class Agregarelemento(list):  # Creamos una clase heredando atributos de list
    def append(self, alumno):  # Definimos que el método append añadirá el elemento alumno
        print("Añadido el alumno", alumno)  # Imprimimos el resultado del método
        super().append(alumno)  # super() llama al método append de la clase padre list

Lista1 = Agregarelemento()  # Definimos la clase de nuestra lista llamada "Lista1"
Lista1.append('Matias')  # Añadimos un elemento a la lista como lo haríamos normalmente
print(Lista1)  # Imprimimos la lista para corroborar que se añadió el alumno
Resultado:
Añadido el alumno Matias
['Matias']

En este caso, cada vez que se añada un elemento a la lista se imprimirá el elemento que se añadió porque así lo definimos (mediante un print) en la clase hija y mediante la función super logramos ejecutar el método («append«) padre de la clase incorporada list.

Espero haber logrado explicarme correctamente. Pero sino, aquí te doy lata nuevamente. El método append pertenece a la clase incorporada list (que es normalmente utilizado para añadir un elemento a una lista).

Pero nosotros logramos añadirlo a una clase hija permitiéndonos así incorporar otro comportamiento adicional que es aplicable a cualquier otra lista a la que se le asigne esta clase hija. Y aunque cambiáramos el nombre de la clase hija (en este caso Agregarelemento) el código funcionaría igual. Fíjate:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# https://pythones.net

class Agregar(list):  # Cambiamos el nombre de la clase por "Agregar"
    def append(self, alumno):  # Creamos método append
        print("Añadido el alumno", alumno)  # Imprimimos el resultado
        super().append(alumno)  # super() escala a la clase padre "list"

Lista1 = Agregar()  # Asignamos a la lista la clase "Agregar"
Lista1.append('Matias')  # Llamamos el método append de Lista1 con el argumento 'Matias'
print(Lista1)  # Imprimimos Lista1
Resultado:
Añadido el alumno Matias
['Matias']

Como ves, cambiamos solo el nombre de la clase y el método append funciona igual porque super en Python 3 permite delegar la llamada del método directamente a la clase padre (principal o superclase) sin especificar en él la clase hija. Este es uno de los beneficios de super en la versión de Python 3.

👉 Super en Python y Herencia múltiple

Aquí es donde super se vuelve, emm… «super(?)». En la herencia múltiple de clases es donde podemos explotar al máximo la función super. Vamos a ver otro ejemplo de herencia múltiple y cómo podemos utilizar la función super en él para llamar métodos de clases padres o bases.

Para este ejemplo vamos a crear la siguiente estructura de clases:

Como ves en el gráfico (horrible pero útil) la clase Shepadoodle hereda de las clases Caniche y Pastor_Aleman que a su vez heredan de la clase principal Perros (Flechas negras para la herencia de clases). Las flechas rojas nos muestran los métodos de cada una.

Dentro de clase principal Perros también tenemos ladrar y gruñir solo que se me olvidó incluirlo en el gráfico.

Ok listos? Ahora revisa el código donde en el método ladrarx utilizamos la función super para multiplicar el ladrido:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# https://pythones.net

class Perros(object):  # Declaramos la clase principal Perros
    def ladrar(self):
        print("GUAAAUU GUAAAUU!")

    def grunir(self):
        print("GRRRRRR GRRRRR")

class Caniche(Perros):  # La clase secundaria hereda de la clase principal Perros
    def ladrar(self):
        print("guau guau guau")

    def grunir(self):
        print("gññññiii gñññiiii")

class Pastor_Aleman(Perros):  # La clase secundaria hereda de la clase principal Perros
    def ladrar(self):
        print("GuaUUU GUAAAUUU GuaUUU")

    def grunir(self):
        print("Agrfgregreff aggrrfsgrrr")

class Shepadoodle(Caniche, Pastor_Aleman):  # La clase hereda de las clases hijas de su padre Perros
    def ladrarx(self, veces):
        for cuantas in range(veces):
            super(Shepadoodle, self).ladrar()

Tommy = Pastor_Aleman()
Piny = Caniche()
Cuchele = Shepadoodle()
Cuchele.ladrarx(5)  # Imprime guau guau guau (5 veces) porque heredó el ladrido de la clase padre CANICHE
                    # Pero si eliminamos o renombramos el método ladrar de CANICHE ¿qué imprimiría?
                    # Imprimiría el ladrido del Pastor_Aleman.
                    # Y si borramos ambos? Imprimirá el ladrido de Perros.

Como ves en la explicación que incluí en los comentarios del código, si nosotros borramos o renombramos el método del cual super está heredando, continuará buscando automáticamente los métodos de las clases superiores.

Ah, y por cierto Shepadoodle es una mezcla de caniche y pastor alemán.

Pero, ¿por qué si nosotros borramos el método «ladrar» de Caniche imprime el de Pastor_Aleman y no recurre a la clase padre Perros?

🌳 MRO (Method Resolution Order)

Porque la función super sigue un árbol de ancestros que se conoce como MRO (Method Resolution Order) que podría traducirse a Resolución de órdenes de métodos.

Como decía, la función super busca siguiendo el orden (MRO) delegando en la primera clase superior por encima de la clase a la que pertenece hasta encontrar el método que estamos indicando. Y siguiendo la secuencia de MRO comienza por buscar desde la clase donde se encuentra la invocación (función super) al método, sus padres, los padres de sus padres y así hasta alcanzar la clase Object, en caso de no encontrarlo antes obviamente.

Fíjate tú mismo con el código que hicimos de ejemplo de ir borrando el método de las clases padres de abajo hacia arriba y ve comprobando cómo interpreta el orden. Si pruebas cambiar el orden de las clases en:

class Shepadoodle(Caniche, Pastor_Aleman):  # La clase hereda de las clases hijas de su padre Perros
    def ladrarx(self, veces):
        for cuantas in range(veces):
            super(Shepadoodle, self).ladrar()

# POR:

class Shepadoodle(Pastor_Aleman, Caniche):  # Cambiamos el orden de las clases
    def ladrarx(self, veces):
        for cuantas in range(veces):
            super(Shepadoodle, self).ladrar()

Verás cómo prefiere el método de la clase Pastor_Aleman antes que la de Caniche.

Esto nos está diciendo que el orden de las clases, importa.

La función super nos va a permitir crear subclases que componen a otras determinando el comportamiento según el orden que le demos a las mismas.

📌 Resumen: ¿Qué hace super()?
  • En herencia simple: Llama al constructor de la clase padre sin nombrarla.
  • En herencia múltiple: Sigue el orden MRO para encontrar el método correcto.
  • Ventaja clave: Permite cambiar el nombre de las clases sin romper el código.

Lo siento, tenía que ponerlo.

🚀 Herencia múltiple y atributos con super en Python

Si hasta ahora vimos cómo heredar atributos de clases con Herencia Simple y cómo heredar Métodos con Herencia Múltiple. Pero, ¿qué pasa con los atributos en la Herencia Múltiple? Pues super() no nos sirve en ese caso. Debemos llamar a los constructores de ambas clases especificándolas por su nombre. Y si cambiamos el nombre u orden de la clase deberemos especificarlo.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# https://pythones.net

class Padre(object):  # Creamos la clase Padre
    def __init__(self, ojos, cejas):  # Definimos los Atributos
        self.ojos = ojos
        self.cejas = cejas

class Madre(object):  # Creamos la clase Madre
    def __init__(self, brazos, piernas):  # Definimos los Atributos
        self.brazos = brazos
        self.piernas = piernas

class Hijo(Padre, Madre):  # Creamos clase hija que hereda de Padre y luego de Madre
    def __init__(self, ojos, cejas, cara, brazos, piernas):  # Constructor de la clase
        Madre.__init__(self, brazos, piernas)  # Llamamos al constructor de Madre
        Padre.__init__(self, ojos, cejas)  # Llamamos al constructor de Padre
        self.cara = cara

Tomas = Hijo('Marrones', 'Negras', 'Larga', 2, 2)
print(Tomas.ojos, Tomas.cejas, Tomas.cara, Tomas.piernas, Tomas.brazos)
Resultado:
Marrones Negras Larga 2 2

⚠️ Importante: En herencia múltiple, para heredar atributos de varias clases padres, no puedes usar super(). Debes llamar explícitamente a cada constructor usando el nombre de la clase.

📊 Resumen: super() en herencia simple vs múltiple
Caso Uso de super() Alternativa
Herencia simple (atributos) super().__init__(atributos) Padre.__init__(self, atributos)
Herencia simple (métodos) super().metodo() Padre.metodo(self)
Herencia múltiple (métodos) super().metodo() (sigue MRO) No recomendado
Herencia múltiple (atributos) ❌ No funciona ✅ Llamar a cada constructor por nombre

Esto ha sido todo y espero hayas logrado comprender algo de esta función que nos va a ser muy útil en un futuro. Hasta luego. Bye bye. Ah, y no olvides compartir, recomendarle a algún amigo interesado en Python o suscribirte a mi blog. Muchas gracias por leerme.

📅 Última actualización: julio 28, 2026

¡Compartir es una forma de agradecer! :)

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio