Aprende leyendo en orden

Problemas de cierre de POO en Python — Pon en código lo que aprendiste

Cuatro ejercicios de repaso de POO en Python: métodos especiales en Point, super() en SavingsAccount, validación con @property en Celsius y polimorfismo del método area() en figuras.

Problema 1: Diseñar una clase Point con métodos especiales

Construye una clase Point que represente una coordenada 2D. Inicializarás los atributos en __init__, definirás qué hace + entre dos puntos con __add__ y darás forma a lo que muestra print() con __str__: tres métodos especiales trabajando juntos.

Cómo se disparan los tres métodos especiales en orden
Point(1, 2)__init__: self.x=1, self.y=2p1 + p2__add__: devuelve Point(4, 6)print(p1 + p2)__str__: "(4, 6)"+print
__init__ asigna los atributos → __add__ devuelve una nueva instancia → __str__ formatea la cadena: cada uno se llama por turno.

Escribe una clase Point que tenga una coordenada x y una coordenada y.

Diséñala de forma que llamar a print(Point(1, 2) + Point(3, 4)) imprima (4, 6) en la pantalla.

Editor Python

Ejecutar el código para ver el resultado

Problema 2: Extender una cuenta bancaria con herencia y super()

Hereda de una clase padre BankAccount para construir una SavingsAccount que pueda aplicar intereses. El patrón es la herencia clásica: llama al inicializador del padre con super().__init__(...) y luego añade los atributos específicos del hijo encima.

Llama a super() para reutilizar el __init__ del padre y luego añade lo tuyo
BankAccount (padre)name / balanceSavingsAccount (hijo)name / balance / rate__init__self.name, self.balance__init__super().__init__(...)añade self.rateapply_interest()balance += balance * rateheredallamada a superextiende
Llamar a super().__init__(...) desde el __init__ del hijo te permite reutilizar la configuración del padre y solo añadir lo nuevo del hijo.

Escribe una clase SavingsAccount que herede de BankAccount. Además del name y el balance del padre, SavingsAccount lleva una tasa de interés rate.

Añade un método apply_interest() que sume los intereses (balance × rate, truncado a entero) al saldo actual. Construye SavingsAccount("Alice", 100000, 0.05), llama a apply_interest() y diseña la clase para que print() muestre Alice: 105000.

Editor Python

Ejecutar el código para ver el resultado

Problema 3: Validar la temperatura con @property

Escribe una clase Celsius que rechace asignaciones por debajo del cero absoluto (-273.15). Usarás @property y un @value.setter para encajar la validación directamente en la asignación de atributos: ese es el patrón clásico de encapsulación.

El setter valida cada asignación
Celsius(25)self.value = 25 → settert.value = -300reasignación → setter25 >= -273.15validación correcta-300 < -273.15validación fallaself._value = 25guardadoraise ValueErrorexcepción
t.value = X parece una asignación normal, pero pasa por el setter, que primero valida el valor. Fuera de rango → ValueError, dentro de rango → se guarda en _value.

Escribe una clase Celsius con un atributo value que lance ValueError("No se permite una temperatura por debajo del cero absoluto") cuando intentes asignar cualquier valor menor que -273.15.

Construye Celsius(25) y muestra la temperatura, luego envuelve una asignación de t.value = -300 en try / except e imprime el mensaje de error con la forma Error: ....

Editor Python

Ejecutar el código para ver el resultado

Problema 4: Usar polimorfismo para calcular áreas en un solo bucle

Da a dos clases distintas un método con el mismo nombre (area()), mete sus instancias en una lista y procésalas con un solo bucle for. A quien las llama no le importa qué clase es cuál: eso es el polimorfismo en pocas palabras.

Mismo nombre de método, comportamiento distinto por tipo
Rectanglewidth × heightlista shapes[Rectangle, Circle]Circleπ × radius²Rectangle.area()= w × hfor shape in shapes:shape.area()Circle.area()= π × r²forsi Rectanglesi Circle
Cuando llamas a shape.area() en cada elemento de la lista, se elige automáticamente el método que coincide con el tipo real del elemento.

Escribe dos clases, Rectangle(width, height) y Circle(radius), ambas con un método area() que devuelve el área. Rectangle calcula ancho × alto y Circle calcula π × radio al cuadrado.

Mete Rectangle(3, 4) y Circle(5) en una lista, recórrela con un bucle e imprime cada área como Área: 12.00, formateada a dos decimales. Usa math.pi para π.

Editor Python

Ejecutar el código para ver el resultado

¡Buen trabajo llegando hasta aquí!

Con esto cierras POO en Python. Has cubierto el diseño de clases e instancias, métodos especiales como __init__ / __add__ / __str__, herencia con super(), encapsulación con @property, polimorfismo, la sentencia with y los type hints: prácticamente todas las herramientas que necesitas para juntar datos y comportamiento en un único tipo. Ahora puedes definir tus propios tipos, añadirles métodos y tratar varios tipos a través de una interfaz compartida.

El siguiente capítulo, Python Intermedio, trata de ir más allá de un solo archivo: organizar módulos y paquetes y usar la biblioteca estándardatetime, os, re, json, collections, dataclasses, asyncio y más— para construir el tipo de procesamiento con el que te vas a encontrar realmente en código de producción.