¿Qué es la función super() y cómo se usa en Python?
La función super() en Python es una herramienta clave para trabajar con la herencia en programación orientada a objetos. Permite a las subclases acceder y extender los métodos y atributos de su superclase sin referenciarlos explícitamente. Esto es muy útil en estructuras de herencia complejas, ya que facilita el mantenimiento y la extensión del código. En esta explicación, descubrirás cómo funciona super() en el contexto de clases de Python y su importancia en la programación orientada a objetos.
¿Cómo se inicializan los atributos en clases con super()?
En el mundo de la programación orientada a objetos, es fundamental definir atributos y métodos de una clase. Los atributos representan las características de la clase, mientras que los métodos definen las acciones que puede realizar. Al construir una clase, el constructor se utiliza para inicializar los atributos.
En Python, una subclase puede heredar atributos y métodos de una superclase utilizando la función super(). Por ejemplo, consideremos una clase Person con atributos como name y age inicializados en su constructor:
classPerson: def __init__(self, name, age): self.name= name
self.age= age
def greet(self):print(f"Hello! I am a person.")
Cuando se crea una subclase Student que hereda de Person, se puede utilizar super() para acceder al constructor de Person y extenderlo, añadiendo atributos propios como student_id:
classStudent(Persona): def __init__(self, name, age, student_id):super().__init__(name, age) self.student_id= student_id
def greet(self):super().saludar()print(f"Hello, my student ID is {self.student_id}.")
¿Cómo funciona el método super() en la herencia múltiple?
La utilidad de super() se extiende a más de un nivel de herencia. Imaginemos una situación en la que tenemos una clase LivingBeing, de la que hereda Person, y a su vez, de la cual hereda Student. Aquí, super() se utiliza para mantener la cadena de inicializaciones:
Con este esquema, super() asegura que todos los niveles de herencia reciban los atributos iniciales adecuados, facilitando una estructura limpia y coherente.
¿Por qué es importante la herencia en la programación orientada a objetos?
La herencia es uno de los cuatro pilares fundamentales de la programación orientada a objetos. Permite reutilizar y extender el código de manera eficiente, lo cual es crucial en la creación de aplicaciones complejas.
Al comprender y aplicar la función super() en Python, los desarrolladores pueden construir sistemas jerárquicos con niveles de abstracción y especialización, promoviendo el diseño de software robusto y mantenible.
Recuerda que la práctica constante y el estudio son esenciales para profundizar en estos conceptos y convertirte en un experto en programación orientada a objetos en Python. Continúa explorando y experimentando con clases y herencia para consolidar tu conocimiento.
🟢 Diferencia entre el atributo y el argumento del constructor
Te habrás fijado que name y self.name parecen ser lo mismo, pues no, son diferentes aunque contengan el mismo valor.
La sentencia self.name hace referencia al atributo del objeto, mientras que name hace referencia al valor del argumento de __init__ cuando se crea una instancia.
Por ejemplo, voy a repetir el código pero con variables diferentes:
Espero que te haya servido. ¡Nunca pares de aprender! 🚀
Muchas gracias por tu aporte
El uso de super() en Python está relacionado con la herencia de clases. Permite llamar métodos o acceder a atributos de la **clase padre** desde una **clase hija**, sin necesidad de referenciar explícitamente el nombre de la clase padre. Es especialmente útil cuando se trabaja con herencia múltiple o se desea extender la funcionalidad de la clase base sin sobrescribir completamente su comportamiento.
### Sintaxis básica de super()
super().metodo\_de\_la\_clase\_padre()
Aquí, super() devuelve un objeto que representa a la clase base, permitiendo llamar a sus métodos o acceder a sus atributos.
### Ejemplo básico con herencia y super()
classAnimal:  def \_\_init\_\_(self, nombre):  self.nombre = nombre     def hacer\_sonido(self):  print("El animal hace un sonido")classPerro(Animal):  def \_\_init\_\_(self, nombre, raza):  \# Llamamos al constructor de la clase padre con super()  super().\_\_init\_\_(nombre)  self.raza = raza     def hacer\_sonido(self):  \# Extendemos la funcionalidad del método de la clase padre  super().hacer\_sonido()  print("El perro ladra")
\# Uso de las clases
mi\_perro = Perro("Firulais","Golden Retriever")print(mi\_perro.nombre)# Firulaismi\_perro.hacer\_sonido() 
#### Salida:
El animal hace un sonido
El perro ladra
### Explicación:
1. **super().\_\_init\_\_(nombre)**: Llama al constructor de la clase base Animal, lo que permite que la clase hija Perro también inicialice la variable nombre que está definida en la clase Animal.
2. **super().hacer\_sonido()**: Llama al método hacer\_sonido de la clase base Animal antes de agregar el comportamiento específico de Perro.
### Beneficios de usar super():
1. **Herencia Múltiple**: En casos donde una clase hereda de múltiples clases, super() sigue el **orden de resolución de métodos (MRO)**, lo que garantiza que se llame al método correcto en la cadena de herencia.
2. **Reutilización**: Permite reutilizar el código de la clase base, extendiendo su funcionalidad sin necesidad de duplicar código.
3. **Mantenibilidad**: Si el nombre de la clase base cambia, no es necesario modificar los métodos que usan super(), ya que no se hace referencia directa a la clase padre.
### Ejemplo con Herencia Múltiple
classMamifero:  def \_\_init\_\_(self, nombre):  self.nombre = nombre  def hacer\_sonido(self):  print("Sonido de mamífero")classVolador:  def \_\_init\_\_(self, velocidad):  self.velocidad = velocidad  def volar(self):  print(f"El animal vuela a {self.velocidad} km/h")classMurcielago(Mamifero, Volador):  def \_\_init\_\_(self, nombre, velocidad):  super().\_\_init\_\_(nombre) # Llama al constructor de Mamifero  Volador.\_\_init\_\_(self, velocidad) # Llama al constructor de Volador
\# Uso de las clases
bat = Murcielago("Batty",50)bat.hacer\_sonido()# Sonido de mamíferobat.volar()# El animal vuela a 50 km/h
En este ejemplo, Murcielago hereda de ambas clases, Mamifero y Volador. super() es útil para llamar al constructor de Mamifero, pero también es necesario llamar explícitamente al constructor de Volador para inicializar velocidad.
### Resumen:
- super() es una herramienta poderosa para interactuar con clases base.
- Facilita la herencia en programas orientados a objetos, permitiendo la reutilización y extensión del comportamiento de las clases padres.
- Es crucial en escenarios de herencia múltiple para seguir el orden correcto de llamadas a métodos.
Excelente!
Muchas gracias por tu aporte
#ahora LivingBegin sera nuestra super claseclassLivingBeing:def__init__(self, name): self.name = name
classPerson(LivingBeing):def__init__(self, name, age):super().__init__(name) self.age = age
classStudent(Person):def__init__(self, name, age, student_id):super().__init__(name, age) self.student_id = student_id
defintroduce(self):print(f"Hi, I am {self.name}, I have {self.age} years old, and my student ID is {self.student_id}")student = Student("Ana",20,"S123")student.introduce()# Hi, I am Ana, I have 20 years old, and my student ID is S123
¡Genial! Nunca pares de aprender 🚀🚀
En Python, super() es una función que te permite acceder a métodos o atributos de una clase padre desde una clase hija. Es especialmente útil en el contexto de la herencia para garantizar que las clases derivadas llamen a los métodos de sus clases base correctamente, evitando sobreescrituras accidentales.
classAnimal:def__init__(self, name): self.name = name
defspeak(self):returnf"{self.name} hace un sonido."classPerro(Animal):def__init__(self, name, breed):# Llama al constructor de la clase padre (Animal)super().__init__(name) self.breed = breed
defspeak(self):# Llama al método speak de la clase padre y lo extiendereturnsuper().speak()+" ¡Guau!"# Crear un objeto de la clase Perromi_perro = Perro("Max","Labrador")print(mi_perro.speak())# Output: Max hace un sonido. ¡Guau!
Se siente como si estas clases de POO estuvieran acomodadas al revez, estando primero las clases mas completas y dificiles y luego donde se explican las bases.
Súper buena Carli!!! Gracias me ayudas bastante, ahora seré tu admiradora para lograr lo mismo que tu!!!
classPlantillaBarcelona: def __init__(self, portero, defensas, mediocampistas, delanteros): self.portero= portero self.defensas= defensas self.mediocampistas= mediocampistas self.delanteros= delanteros def mostrar_plantilla(self):return f"Portero: {self.portero}\nDefensas: {', '.join(self.defensas)}\nMediocampistas: {', '.join(self.mediocampistas)}\nDelanteros: {', '.join(self.delanteros)}"#Creación de Plantillas de diferentes años mediante herenciaclass PlantillaBarcelona2025(PlantillaBarcelona): def __init__(self):super().__init__( portero="Wojhciech Szczesny", defensas=["Jules Koundé","Ronald Araújo","Andreas Christensen","Alejandro Balde"], mediocampistas=["Frenkie de Jong","Pedri","Gavi"], delanteros=["Robert Lewandowski","Raphinha","Lamine Yamal"])classPlantillaBarcelona2024(PlantillaBarcelona): def __init__(self):super().__init__( portero="Marc-André ter Stegen", defensas=["Jules Koundé","Ronald Araújo","Andreas Christensen","Alejandro Balde"], mediocampistas=["Frenkie de Jong","Gavi","Ilkay Gündogan"], delanteros=["Robert Lewandowski","Raphinha","Ferran Torres"])classPlantillaBarcelona2023(PlantillaBarcelona): def __init__(self):super().__init__( portero="Marc-André ter Stegen", defensas=["Jules Koundé","Ronald Araújo","Andreas Christensen","Jordi Alba"], mediocampistas=["Sergio Busquets","Pedri","Frenkie de Jong"], delanteros=["Robert Lewandowski","Raphinha","Ansu Fati"])classPlantillaBarcelona2022(PlantillaBarcelona): def __init__(self):super().__init__( portero="Marc-André ter Stegen", defensas=["Dani Alves","Gerard Piqué","Eric Garcia","Jordi Alba"], mediocampistas=["Sergio Busquets","Pedri","Gavi"], delanteros=["Pierre-Emerick Aubameyang","Ferran Torres","Ousmane Dembélé"])plantilla_2025 =PlantillaBarcelona2025()plantilla_2024 =PlantillaBarcelona2024()plantilla_2023 =PlantillaBarcelona2023()plantilla_2022 =PlantillaBarcelona2022()
porque no se uso super en el codigo de los vehiculos anteriores?
La transcripción no proporciona una explicación específica sobre por qué no se usó 'super' en el código de los vehículos, solo muestra la implementación de las clases sin mencionar el uso de 'super'.
Ese punto aun no se había tocado y tocaba en esta clase. Al final del curso podemos optimizar todos los códigos vistos con todo el aprendizaje obtenido. Recuerda la primera clase: print("Hola mundo!")
En el caso en que una clase herede de dos clases o mas, como podemos hacer referencia al super de la clase que queremos inicializar o manipular?
Ejemplo:
class Clase3(Clase1, Clase2):
def __init_(self, param1, param2, param3):
# Como se llama al constructor de Clase1 y Clase2, se puede usar super() para llamar al constructor de la primera clase en el orden de herencia ?
class Estudiante:
# El constructor
def __init__(self, nombre, edad, grado):
self.nombre = nombre # Inicializamos los atributos
super() no repite el código: lo conecta y lo mejora.
Es la clave para escribir programas más limpios, reutilizables y fáciles de mantener.
Lo que yo pensabas antes
Creía que super()rompía las reglas de la POO porque parecía que duplicaba atributos y funciones, haciendo que las clases hijas repitieran lo que ya existía en las clases padres.
Parecía que todo el orden de la herencia, encapsulación y reutilización se perdía.
Lo que realmente es
super()no rompe nada, al contrario: refuerza los principios de la POO.
Sirve para reutilizar el código de la clase padre, evitar duplicar lógica y mantener el programa fácil de actualizar.
Si el día de mañana cambiamos algo en el padre, el cambio se aplica automáticamente a todas las hijas que usan super().
Cuándo usar super() (y por qué es clave)
✅ Cuando la clase hija tiene atributos o funciones adicionales:
super() nos permite heredar los originales y solo agregar lo nuevo, sin reescribir todo.
✅ Cuando queremos extender un método:
podemos ejecutar el método del padre y luego añadir nuestro propio comportamiento.
OJO:Cuando la hija no necesita nada extra, simplemente no lo usamos; hereda todo automáticamente.
Si la class Student es heredada de Person, ¿Por qué debo definir el constructor nuevamente para atributos name y age si ya los tenia la calse persona?
La razón es que cuando defines un método __init__ en la clase hija (Student), este sobrescribe (reemplaza) completamente al __init__ de la clase padre (Person). El programa ya no ejecutará automáticamente el constructor del padre.
Al definir un método __init__ en la clase hija, este reemplaza por completo al __init__ de la clase padre. La herencia de métodos no es "aditiva" para el constructor; es una sustitución.
No es necesario pedir todos los atributos de la clase padre al crear una clase heredada. Puedes definir solo los atributos que realmente necesitas en la subclase. Si solo deseas usar uno de los atributos de la clase padre, puedes hacerlo. Sin embargo, es recomendable seguir las buenas prácticas de programación, asegurando que la herencia tenga sentido en el contexto de tu diseño. Utilizar super() te permitirá acceder a los métodos y atributos de la clase padre cuando sea necesario.
Hola, por que es necesario usar super().greet() en el metodo greet?
super() permite acceder al comportamiento del método greet de la superclase o clase padre. Esto permite extender o modificar el comportamiento heredado sin perder la funcionalidad que ya se ha definido en la superclase.
En este caso se busca que el estudiante salude mencionando su student_id el cual es un atributo propio de la clase Student y no de Person. Por ende el método greet debe ser personalizado para que la salida muestre además del Hello! I am a person. el mensaje personalizado Hello, my student ID is 18723.
Cuando tu heredas automaticamente puedes usar el metodo de la clase padre y obtendras el comportamiento que le diste alla. Lo que pasa es que aqui uso polimorfismo, uso el mismo metodo y le cambio el comportamiento. Ahora bien, uso dentro de ese metodo super().greet() es porque queria traer el comportamiento del padre y añadirle el comportamiento del hijo, es por eso que en consola ves ambos print.
5:19 cuando se creo el student y se llamó a Student(), en la respuesta no salió ni nombre ni edad , no le imprimió " Hello! I am a Person", no es un error eso??? , sino para que le coloco atributos??
Hola, en el minuto 5:19, en el código no se llama a los atributos name y age, por eso no los muestra. Se puede agregar en el código la siguiente línea a la clase Student, en el método greet:
def greet(self):
super().greet()
print(f"Hola. Mi nombre es {self.name}, tengo {self.age} años. Mi código de estudiante es: {self.student_id}").
Lo probé y me muestra los atributos name y age.
Habrá ocasiones en las que no queramos heredar todos los atributos del padre tal como están, especialmente cuando necesitamos agregar nuevos. Por ejemplo, una clase Persona puede tener los atributos nombre y edad, mientras que una clase Estudiante debería tener, además, un atributo adicional como student_id.
En estos casos, es necesario sobrescribir el método __init__ en la subclase para incluir los nuevos atributos.
Para evitar duplicar código y asegurarnos de que los atributos heredados se inicialicen correctamente, utilizamos super(), que nos permite llamar al constructor y a otros métodos de la clase padre.
En este ejemplo, también podríamos usar super() para reutilizar o extender métodos como greet, si quisiéramos personalizar el saludo del estudiante sin perder la lógica base de la clase Persona.
Algo que he notado, es que en Python, no necesitas declarar de manera especial un método de la clase base que tiene implementación, para que en la clase hija se redefina dicha implementación.
En C·# cuando tienes un método que tiene implementación (no abstracto) en una clase Padre, y quieres que opcionalmente una clase Hija pueda cambiar esa implementación, se declara dicho método como "virtual". Y si la clase Hija desea redefinir dicha implementación (cambiar la lógica) debe indicar el método como "override".
En Python noto que no se establece algo similar. Puedes sobreescribirlo sin problemas. Puedes sobreescribir el método pero a su vez, ejecutando los métodos de la clase Padre usando base().
Si solo sobreescribimos o hacemos una sobrecarga de un método heredado en Python, este método es el que manda y ya no se hereda el método de la clase Padre. Es por ello que opcionalmente tienes la opción de Base() para asegurarte que también se ejecute la lógica de la clase Padre.
Veamos algunas pruebas validando lo mencionado:
También un buen recurso para entender más a profundo como funciona el super() es este:
Otra manera de hacer doble herencia seria:
classLivingBeing:def__init__(self,name): self.name = name
classPerson(LivingBeing):#Atributosdef__init__(self, name, age):super().__init__(name) self.age = age
#Metodosdefgreet(self):print(f"Hello! Im {self.name}, Im {self.age}")#Clase estudiante que va a heredar de personaclassStudent(Person):#Atributosdef__init__(self, name, age, student_id):#Llamar a la clase padre o superclase Person para los atributos de TODAS las personassuper().__init__(name, age)#Atributo que solo tiene Student self.student_id = student_id
defintroduce(self):#llamar al metodo de Personasuper().greet()#Pero se va a alterar un poco asi:print(f"Im also a student. My ID is {self.student_id}")student = Student("Mateo",27,"123458")student.introduce()```classLivingBeing:def \_\_init\_\_(*self*,*name*):*self*.name =*name*classPerson(LivingBeing):#Atributos def \_\_init\_\_(*self*, *name*, *age*): super().\_\_init\_\_(*name*) *self*.age = *age*#Metodos def greet(*self*): print(f"Hello! Im {*self*.name}, Im {*self*.age}")\#Clase estudiante que va a heredar de personaclass Student(Person):#Atributos def \_\_init\_\_(*self*, *name*, *age*, *student\_id*): #Llamar a la clase padre o superclase Person para los atributos de TODAS las personas super().\_\_init\_\_(*name*, *age*) #Atributo que solo tiene Student *self*.student\_id = *student\_id*defintroduce(*self*):#llamar al metodo de Persona super().greet() #Pero se va a alterar un poco asi: print(f"Im also a student. My ID is {*self*.student\_id}")student = Student("Mateo",27,"123458")student.introduce()
No logro comprender la funcionalidad del super, si en la clase persona comentas la linea del codigo del super sigue funcionando correctamente