@abstractmethod-2
- Obtener enlace
- X
- Correo electrónico
- Otras aplicaciones
Clases Abstractas en Python: La Fábrica de Juguetes 🏭🧸
Imagina que tienes una fábrica de juguetes. No produces juguetes genéricos, sino tipos específicos: carros, muñecas y rompecabezas.
La idea principal
Una clase abstracta es como el plano general de la fábrica:
from abc import ABC, abstractmethod
class Juguete(ABC): # Este es nuestro "plano general"
@abstractmethod
def hacer_sonido(self):
pass # ¡No sabemos qué sonido hará cada juguete!
@abstractmethod
def mover(self):
pass # ¡No sabemos cómo se moverá cada juguete!¿Por qué usar clases abstractas?
❌ NO PUEDES crear un "juguete genérico"
# Esto NO funciona - da error!
juguete_generico = Juguete() # TypeError!✅ SÍ PUEDES crear juguetes específicos
class Carro(Juguete):
def hacer_sonido(self):
return "¡Run run! 🚗"
def mover(self):
return "Rodando por el piso"
class Munieca(Juguete):
def hacer_sonido(self):
return "¡Hola! 👋"
def mover(self):
return "Caminando elegantemente"Ejemplo completo: Nuestra fábrica en acción
from abc import ABC, abstractmethod
# El plano maestro (clase abstracta)
class Juguete(ABC):
@abstractmethod
def hacer_sonido(self):
pass
@abstractmethod
def mover(self):
pass
# Método concreto - TODOS los juguetes lo heredan
def presentarse(self):
return f"Soy un juguete y {self.mover()}"
# Juguetes específicos
class Carro(Juguete):
def hacer_sonido(self):
return "¡Run run! 🚗"
def mover(self):
return "rodando por el piso"
class Munieca(Juguete):
def hacer_sonido(self):
return "¡Hola! 👋"
def mover(self):
return "caminando elegantemente"
# ¡A jugar!
carro_rojo = Carro()
munieca_lucia = Munieca()
print(carro_rojo.hacer_sonido()) # ¡Run run! 🚗
print(munieca_lucia.presentarse()) # Soy un juguete y caminando elegantementeAnalogía del restaurante 🍽️
Clase abstracta = Receta base de "pizza"
Obligatorio: tener masa, queso, ingredientes
Opcional: método para hornear (ya está implementado)
Clases concretas = Pizzas específicas
PizzaMargherita, PizzaPepperoni, PizzaHawaiana
Cada una define SUS ingredientes específicos
¿Cuándo usar clases abstractas?
Cuando quieres un contrato: "Todos los que hereden de mí DEBEN implementar estos métodos"
Para organizar código: Agrupar funcionalidad común
Para evitar errores: Python te avisa si olvidas implementar un método obligatorio
Resumen visual
JUGUETE (Abstracta) ← No se puede instanciar
├── debe tener: hacer_sonido() ❗
├── debe tener: mover() ❗
└── ya tiene: presentarse() ✅
│
├── CARRO (Concreta)
│ ├── hacer_sonido() = "¡Run run!"
│ └── mover() = "Rodando"
│
└── MUÑECA (Concreta)
├── hacer_sonido() = "¡Hola!"
└── mover() = "Caminando"¡Así garantizas que todos tus juguetes se comporten como juguetes! 🎯
@classmethod en Python: El Director de la Fábrica 🎬🏭
Imagina que tienes una fábrica de pizzas donde el director (classmethod) puede tomar decisiones sobre cómo crear pizzas sin necesidad de que exista una pizza específica.
La idea principal
Un @classmethod es un método que trabaja con la clase misma, no con instancias específicas.
class Pizza:
def __init__(self, ingredientes):
self.ingredientes = ingredientes
# Método normal - trabaja con UNA pizza específica
def describir(self):
return f"Pizza con: {', '.join(self.ingredientes)}"
# Classmethod - trabaja con la CLASE Pizza
@classmethod
def margherita(cls):
return cls(["salsa tomate", "mozzarella", "albahaca"])
@classmethod
def pepperoni(cls):
return cls(["salsa tomate", "mozzarella", "pepperoni"])Analogía del Restaurante de Pizzas 🍕
El Chef vs El Director
Métodos normales = Chef individual (trabaja con una pizza específica)
@classmethod = Director del restaurante (crea recetas estándar)
class Pizza:
def __init__(self, nombre, ingredientes):
self.nombre = nombre
self.ingredientes = ingredientes
# Método normal - el chef trabajando
def cocinar(self):
return f"Cocinando {self.nombre} 🍕"
# Classmethod - el director creando recetas estándar
@classmethod
def crear_margherita(cls):
return cls("Margherita", ["salsa", "mozzarella", "albahaca"])
@classmethod
def crear_cuatro_quesos(cls):
return cls("Cuatro Quesos", ["mozzarella", "gorgonzola", "parmesano", "fontina"])
@classmethod
def crear_personalizada(cls, nombre, *ingredientes):
return cls(nombre, list(ingredientes))
# ¡A trabajar!Diferencia clave: cls vs self
class FabricaJuguetes:
material = "plástico" # Atributo de CLASE
def __init__(self, color):
self.color = color # Atributo de INSTANCIA
# Método normal - usa self
def pintar(self, nuevo_color):
self.color = nuevo_color # Cambia UNA instancia
# Classmethod - usa cls
@classmethod
def cambiar_material_fabrica(cls, nuevo_material):
cls.material = nuevo_material # Cambia TODAS las instanciasEjemplos prácticos en acción
Ejemplo 1: Fábrica de Empleados
class Empleado:
empresa = "TechCorp"
def __init__(self, nombre, salario):
self.nombre = nombre
self.salario = salario
# Classmethod para crear empleados estándar
@classmethod
def crear_gerente(cls, nombre):
return cls(nombre, salario=50000)
@classmethod
def crear_desarrollador(cls, nombre):
return cls(nombre, salario=40000)
@classmethod
def cambiar_empresa(cls, nueva_empresa):
cls.empresa = nueva_empresa
# Uso
gerente = Empleado.crear_gerente("Ana") # No necesita instancia existente
dev = Empleado.crear_desarrollador("Luis")
print(gerente.salario) # 50000
print(dev.salario) # 40000
# Cambio que afecta a TODOS
Empleado.cambiar_empresa("MetaTech")
print(gerente.empresa) # MetaTech
print(dev.empresa) # MetaTechEjemplo 2: Sistema de Conversiones
class Temperatura:
def __init__(self, celsius):
self.celsius = celsius
@classmethod
def desde_fahrenheit(cls, fahrenheit):
celsius = (fahrenheit - 32) * 5/9
return cls(celsius)
@classmethod
def desde_kelvin(cls, kelvin):
celsius = kelvin - 273.15
return cls(celsius)
# Diferentes formas de crear temperaturas
t1 = Temperatura(25) # 25°C directamente
t2 = Temperatura.desde_fahrenheit(77) # 25°C desde Fahrenheit
t3 = Temperatura.desde_kelvin(298.15) # 25°C desde Kelvin
print(f"Todas son 25°C: {t1.celsius}, {t2.celsius}, {t3.celsius}")¿Cuándo usar @classmethod?
✅ SÍ usar classmethod cuando:
Métodos de fábrica: Crear instancias de diferentes maneras
Manipular atributos de clase: Cambios que afecten a TODAS las instancias
Métodos alternativos de construcción: Como
desde_json(),desde_csv()
❌ NO usar classmethod cuando:
Necesitas trabajar con datos de una instancia específica
El método no necesita acceso a la clase
Resumen visual
FÁBRICA DE PIZZAS 🏭
DIRECTOR (@classmethod)
├── crear_margherita() → Pizza Margherita
├── crear_pepperoni() → Pizza Pepperoni
└── cambiar_receta() → Afecta a TODAS
CHEF (método normal)
├── cocinar() → Esta pizza específica
├── cortar() → Esta pizza específica
└── servir() → Esta pizza específicaVentajas clave
Flexibilidad: Múltiples formas de crear objetos
Organización: Lógica de creación agrupada en la clase
Coherencia: Métodos que trabajan a nivel de clase, no de instancia
¡Así el director (classmethod) puede crear "recetas estándar" sin ensuciarse las manos con pizzas individuales!
- Obtener enlace
- X
- Correo electrónico
- Otras aplicaciones
Comentarios
Publicar un comentario