Programación Orientada a Objetos
La POO es un paradigma que organiza el código en clases y objetos. Una clase es un molde/plantilla, y un objeto es una instancia concreta de esa clase.
Conceptos clave: Clase, Objeto, Atributo, Método, Constructor.
class Alumno:
"""Clase que representa a un alumno."""
# Constructor: se ejecuta al crear el objeto
def __init__(self, nombre, edad, legajo):
self.nombre = nombre # atributo de instancia
self.edad = edad
self.legajo = legajo
self.notas = [] # lista vacía inicial
# Método para agregar notas
def agregar_nota(self, nota):
self.notas.append(nota)
# Método que calcula el promedio
def promedio(self):
if not self.notas:
return 0
return sum(self.notas) / len(self.notas)
# Representación en string del objeto
def __str__(self):
return f"Alumno: {self.nombre} (Legajo: {self.legajo})"
# Crear objetos (instancias)
alumno1 = Alumno("María", 16, "A001")
alumno2 = Alumno("Carlos", 17, "A002")
alumno1.agregar_nota(8)
alumno1.agregar_nota(9)
alumno1.agregar_nota(7)
print(alumno1) # Alumno: María (Legajo: A001)
print(f"Promedio: {alumno1.promedio():.2f}") # 8.00
Herencia
La herencia permite crear una clase nueva (hija) basada en una existente (padre), reutilizando y extendiendo su funcionalidad.
# Clase padre (base)
class Persona:
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
def saludar(self):
print(f"Hola, soy {self.nombre}")
# Clase hija (hereda de Persona)
class Docente(Persona):
def __init__(self, nombre, edad, materia):
super().__init__(nombre, edad) # llama al init del padre
self.materia = materia
# Sobrescribimos (override) el método saludar
def saludar(self):
print(f"Hola, soy el profe {self.nombre} y doy {self.materia}")
def tomar_examen(self):
print(f"El profe {self.nombre} está tomando examen de {self.materia}")
# Uso
gatica = Docente("Gatica", 35, "Programación")
gatica.saludar() # Método sobreescrito
gatica.tomar_examen() # Método propio de Docente
# Verificar herencia
print(isinstance(gatica, Docente)) # True
print(isinstance(gatica, Persona)) # True (hereda)
Manejo de Excepciones
Los errores en tiempo de ejecución se llaman excepciones.
Python permite capturarlas y manejarlas con try / except / finally.
# Estructura básica
try:
numero = int(input("Ingresá un número: "))
resultado = 100 / numero
print(f"100 / {numero} = {resultado}")
except ValueError:
print("Error: ingresaste texto, no un número")
except ZeroDivisionError:
print("Error: no se puede dividir por cero")
except Exception as e:
print(f"Error inesperado: {e}")
finally:
print("Este bloque siempre se ejecuta")
# Lanzar excepciones propias
def validar_edad(edad):
if edad < 0 or edad > 120:
raise ValueError(f"Edad inválida: {edad}")
return edad
try:
validar_edad(-5)
except ValueError as e:
print(f"Capturado: {e}")
Manejo de Archivos
Python puede leer y escribir archivos de texto fácilmente con la función open().
# Escribir en un archivo (crea o sobreescribe)
with open("alumnos.txt", "w", encoding="utf-8") as archivo:
archivo.write("Ana García\n")
archivo.write("Luis Martínez\n")
archivo.write("Pedro Sánchez\n")
# Leer todo el archivo
with open("alumnos.txt", "r", encoding="utf-8") as archivo:
contenido = archivo.read()
print(contenido)
# Leer línea por línea
with open("alumnos.txt", "r", encoding="utf-8") as archivo:
for linea in archivo:
print(linea.strip()) # .strip() elimina \n
# Agregar contenido sin borrar (modo "a")
with open("alumnos.txt", "a", encoding="utf-8") as archivo:
archivo.write("María López\n")
# Modos: "r" leer | "w" escribir | "a" agregar | "r+" leer y escribir
El bloque with open(...) as f: cierra el archivo automáticamente al terminar, incluso si hay un error.
Módulos y Librerías
Python incluye una librería estándar enorme. Podés importar módulos para extender las capacidades del lenguaje sin instalar nada.
import random
import math
import datetime
from os import path
# random — números aleatorios
numero = random.randint(1, 100)
opciones = ["piedra", "papel", "tijera"]
eleccion = random.choice(opciones)
# math — funciones matemáticas
print(math.sqrt(144)) # 12.0 — raíz cuadrada
print(math.pi) # 3.14159...
print(math.ceil(3.2)) # 4 — redondear arriba
print(math.floor(3.8)) # 3 — redondear abajo
# datetime — fechas y tiempos
hoy = datetime.date.today()
ahora = datetime.datetime.now()
print(f"Hoy es: {hoy}")
print(f"Hora actual: {ahora.strftime('%H:%M:%S')}")
Crear tu propio módulo
# archivo: utilidades.py
def es_primo(n):
if n < 2: return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0: return False
return True
# archivo: main.py
from utilidades import es_primo
print(es_primo(17)) # True
print(es_primo(10)) # False
Ejercicios Resueltos
Implementá una clase que simule una cuenta bancaria con depósito, extracción y saldo.
- 1Creamos la clase con atributos titular y saldo.
- 2El método depositar() valida que el monto sea positivo.
- 3El método extraer() verifica que haya saldo suficiente.
- 4Usamos raise ValueError para errores de negocio.
class CuentaBancaria:
def __init__(self, titular, saldo_inicial=0):
self.titular = titular
self.__saldo = saldo_inicial # privado
def depositar(self, monto):
if monto <= 0:
raise ValueError("El monto debe ser positivo")
self.__saldo += monto
print(f"Depositado: ${monto:,.2f}. Saldo: ${self.__saldo:,.2f}")
def extraer(self, monto):
if monto <= 0:
raise ValueError("El monto debe ser positivo")
if monto > self.__saldo:
raise ValueError("Saldo insuficiente")
self.__saldo -= monto
print(f"Extraído: ${monto:,.2f}. Saldo: ${self.__saldo:,.2f}")
@property
def saldo(self):
return self.__saldo
def __str__(self):
return f"Cuenta de {self.titular} — Saldo: ${self.__saldo:,.2f}"
# Uso
cuenta = CuentaBancaria("Ana López", 1000)
cuenta.depositar(500)
cuenta.extraer(200)
print(cuenta)
Ejercicios Propuestos
Diseñá una jerarquía de clases: Vehiculo → Auto, Moto, Camion.
- Cada vehículo tiene: marca, modelo, año, velocidad_max.
- Método
acelerar(km)que incrementa la velocidad actual. - Método
frenar(km)que la decrementa (no puede ser negativa). - Camión también tiene
carga_maximay métodocargar(toneladas).
Creá una agenda que guarde y cargue contactos desde un archivo de texto.
- Cada contacto: nombre, teléfono, email.
- Guardar en formato CSV (nombre,teléfono,email).
- Al iniciar, cargar los contactos existentes del archivo.
- Menú: agregar, buscar, eliminar, mostrar todos.