class: center, middle, inverse, title-slide .title[ #
Introducción a Python
] .subtitle[ ##
Clase 9: Introduccion a OOP
] .author[ ### Daniel Miles Touya
Máster en Análisis de Datos · UdelaR-Uvigo
] .date[ ### 24 abril 2026 ] --- --- class: inverse, middle .huge[Clase Extra · OOP] <br> ## Qué es una clase --- # Guía de lectura .smallest[ Hasta ahora: - datos (listas, dict, DataFrame) - funciones sobre esos datos ] -- .div_bloque[ Problema: > datos y funciones están separados ] --- # El problema ```python nombre_1 = "Ana" notas_1 = [8, 7, 9] def media(notas): return sum(notas) / len(notas) ``` -- .smallest[ Hay que recordar: - qué datos van juntos ] --- # Problema real .div_bloque[ Escala mal ] -- .smallest[ - 50 alumnos → 150 variables - fácil mezclar datos ] --- # Idea de OOP .div_bloque[ Unir datos + comportamiento ] -- .smallest[ → en un objeto ] --- # Solución ```python class Alumno: def __init__(self, nombre, notas): self.nombre = nombre self.notas = notas ``` --- # Uso ```python ana = Alumno("Ana", [8, 7, 9]) print(ana.nombre) ``` -- .smallest[ Los datos están dentro del objeto ] --- # Añadir comportamiento ```python class Alumno: def __init__(self, nombre, notas): self.nombre = nombre self.notas = notas def media(self): return sum(self.notas) / len(self.notas) ``` --- # Uso ```python ana = Alumno("Ana", [8, 7, 9]) print(ana.media()) ``` --- # Idea clave .div_bloque[ El objeto sabe operar sobre sus datos ] --- # Analogía .div_bloque[ Clase = molde Instancia = objeto concreto ] -- .smallest[ - clase → Alumno - instancia → ana, bob ] --- # Ejemplo ```python ana = Alumno("Ana", [8, 7]) bob = Alumno("Bob", [5, 6]) ``` -- .smallest[ Misma clase → datos distintos ] --- # Idea clave .div_bloque[ Cada objeto es independiente ] --- # Ya usabas OOP ```python import pandas as pd df = pd.DataFrame({"a": [1, 2, 3]}) print(type(df)) ``` -- .smallest[ DataFrame es una clase ] --- # Ejemplos reales .smallest[ - list - dict - DataFrame - Figure (matplotlib) ] --- # Idea profunda .div_bloque[ Todo en Python es un objeto ] --- # Clase vs instancia .smallest[ Clase: - definición ] -- .smallest[ Instancia: - objeto concreto ] --- # Mini ejercicio 1 .smallest[ Identifica: ```python ana = Alumno("Ana", [8, 7]) ``` - ¿qué es la clase? - ¿qué es la instancia? ] --- # Mini ejercicio 2 .smallest[ ¿Por qué esto es problemático? ] ```python nombre_1 = "Ana" nombre_2 = "Bob" ``` --- # Mini ejercicio 3 .smallest[ ¿Qué ventaja tiene esto? ] ```python ana.media() ``` --- # Idea clave .div_bloque[ No pasas datos → ya están dentro ] --- # Lectura de código .div_bloque[ Cuando veas: ```python obj.metodo() ``` -- .smallest[ → el objeto usa sus propios datos ] --- # Qué debes entender .smallest[ - problema sin OOP - clase vs instancia - objeto = datos + comportamiento ] -- .div_bloque[ .hi-blue[Idea final:] > OOP organiza el código agrupando datos y funciones. ] --- # Parte II · Anatomía de una clase class: inverse, middle .huge[Cómo funciona una clase] <br> ## __init__, self, atributos --- # Guía de lectura .smallest[ Ya sabemos: - qué es una clase - qué es una instancia ] -- .div_bloque[ Ahora: > cómo funciona por dentro ] --- # __init__ .div_bloque[ Se ejecuta al crear el objeto ] --- ```python class Alumno: def __init__(self, nombre): self.nombre = nombre ``` --- # Qué pasa .smallest[ Alumno("Ana") hace: 1. crea objeto 2. llama a __init__ 3. guarda datos ] --- # Idea clave .div_bloque[ __init__ inicializa el objeto ] --- # self .div_bloque[ self = el objeto actual ] --- ```python ana = Alumno("Ana") ``` -- .smallest[ self es ana dentro de la clase ] --- # Equivalencia ```python ana.metodo() ``` -- .smallest[ es igual a: ] ```python Alumno.metodo(ana) ``` --- # Idea clave .div_bloque[ Python pasa self automáticamente ] --- # Atributos .div_bloque[ Datos del objeto ] --- ```python self.nombre = nombre self.notas = notas ``` -- .smallest[ Se guardan dentro del objeto ] --- # Parámetro vs atributo ```python def __init__(self, nombre): parametro = nombre self.nombre = nombre ``` -- .smallest[ parametro → desaparece self.nombre → permanece ] --- # Uso ```python print(ana.nombre) ``` --- # Métodos .div_bloque[ Funciones dentro de la clase ] --- ```python def media(self): return sum(self.notas) / len(self.notas) ``` --- # Uso ```python ana.media() ``` --- # Idea clave .div_bloque[ Los métodos usan self para acceder a datos ] --- # Atributos de instancia .div_bloque[ Cada objeto tiene los suyos ] --- ```python ana.notas bob.notas ``` -- .smallest[ son distintos ] --- # Atributos de clase .div_bloque[ Compartidos por todos ] --- ```python class Pizza: precio = 10 ``` --- # Uso ```python print(Pizza.precio) ``` -- .smallest[ y también: ] ```python p = Pizza() print(p.precio) ``` --- # Diferencia clave .smallest[ instancia: - self.x ] -- .smallest[ clase: - Clase.x ] --- # Mini ejercicio 1 .smallest[ ¿Qué imprime? ] ```python class A: def __init__(self, x): self.x = x a = A(5) print(a.x) ``` --- # Mini ejercicio 2 .smallest[ ¿Qué es self? ] ```python class A: def f(self): print(self) a = A() a.f() ``` --- # Mini ejercicio 3 .smallest[ Error: ] ```python class A: def __init__(x, y): x.y = y ``` -- .div_bloque.small[ .hi-red[Problema:] falta self correctamente ] --- # Mini ejercicio 4 .smallest[ ¿Qué diferencia hay? ] ```python self.x = 5 x = 5 ``` --- # Error típico .div_bloque[ Olvidar self ] -- .smallest[ muy común al empezar ] --- # Conexión con curso .div_bloque[ Esto ya lo usabas: ] --- ```python df["col"] df.mean() ``` -- .smallest[ df es objeto → métodos + datos ] --- # Qué debes entender .smallest[ - __init__ - self - atributos - métodos - instancia vs clase ] -- .div_bloque[ .hi-blue[Idea final:] > self conecta los datos con las funciones del objeto. ] --- # Parte III · OOP en la práctica class: inverse, middle .huge[Cuándo usar clases] <br> ## Uso real --- # Pregunta clave .div_bloque[ ¿Siempre usar clases? ] -- .div_bloque.small[ .hi-red[NO] ] --- # Regla práctica .smallest[ Usar clases cuando: - hay estructura - hay varias operaciones - hay estado ] --- # Caso típico .div_bloque[ Objeto con datos + operaciones ] --- ```python class Cuenta: def __init__(self, saldo): self.saldo = saldo def depositar(self, x): self.saldo += x def retirar(self, x): self.saldo -= x ``` --- # Uso ```python c = Cuenta(100) c.depositar(50) c.retirar(30) print(c.saldo) ``` --- # Idea clave .div_bloque[ El objeto cambia con el tiempo ] --- # Caso 2 · Configuración .div_bloque[ Objeto que guarda parámetros ] --- ```python class Modelo: def __init__(self, alpha): self.alpha = alpha def predecir(self, x): return x * self.alpha ``` --- # Uso ```python m = Modelo(2) print(m.predecir(3)) ``` --- # Conexión con IA .div_bloque[ Muchos modelos funcionan así ] -- .smallest[ - sklearn - tensorflow ] --- # Caso 3 · Agrupar lógica .div_bloque[ Evitar pasar muchos argumentos ] --- ```python def procesar(datos, parametros, config): ... ``` -- .smallest[ vs ] ```python obj.procesar() ``` --- # Cuándo NO usar clases .div_bloque[ Casos simples ] -- .smallest[ - una función - cálculo puntual ] --- # Ejemplo ```python def cuadrado(x): return x**2 ``` -- .smallest[ No necesita clase ] --- # Comparación .smallest[ Sin clase: ] ```python media(notas) ``` -- .smallest[ Con clase: ] ```python alumno.media() ``` --- # Ventaja .div_bloque[ Código más organizado ] --- # Desventaja .div_bloque[ Más complejo ] --- # Patrón real (pandas) ```python df.mean() df.plot() ``` -- .smallest[ df es un objeto ] --- # Patrón real (matplotlib) ```python fig, ax = plt.subplots() ax.plot(...) ``` --- # Mini ejercicio 1 .smallest[ ¿Usarías clase? ] - calcular suma - gestionar cuentas bancarias ] --- # Mini ejercicio 2 .smallest[ Transforma esto en clase: ] ```python def area(r): return 3.14 * r**2 ``` --- # Mini ejercicio 3 .smallest[ ¿Qué ventaja tiene? ] ```python obj.metodo() ``` --- # Error típico .div_bloque[ Usar clases para todo ] -- .smallest[ No siempre es necesario ] --- # Idea clave .div_bloque[ Elegir la herramienta adecuada ] --- # Qué debes entender .smallest[ - cuándo usar clases - cuándo no - ejemplos reales - conexión con librerías ] -- .div_bloque[ .hi-blue[Idea final:] > OOP es útil cuando hay estructura y estado. ]