Encapsulación en Python: atributos privados y métodos getter/setter
Clase 4 de 17 • Curso de Python Orientado a Objetos
Resumen
La encapsulación en Python te ayuda a proteger datos sensibles y a mantener la integridad de tu aplicación. Con un ejemplo claro de una biblioteca, se muestra cómo controlar el acceso a los atributos internos con atributos privados, validaciones y métodos getter y setter para evitar inconsistencias.
¿Qué es la encapsulación en Python y cómo protege tus datos?
La idea es simple: como en un banco, no accedes a la bóveda, hablas con el cajero. En Python, la encapsulación oculta los detalles internos de una clase y controla el acceso a los datos. En un sistema de biblioteca, esto asegura la integridad de datos: nadie debería alterar desde fuera el estado real de un libro.
¿Cómo evitar inconsistencias con préstamos y disponibilidad?
- Controla el flujo con un atributo de disponibilidad: si está disponible, se presta; si no, se informa que “no está disponible”.
- Evita retornos implícitos de None: devuelve un mensaje claro cuando no se puede prestar.
- Incrementa un contador interno de veces prestado al ejecutar el método prestar.
- Usa espopular para evaluar si un libro es popular: retorna true si fue prestado más de cinco veces.
¿Qué problema surge al modificar datos directamente?
- Si desde fuera haces libro.veces_prestado = 10, el sistema mostrará “total préstamos 11” sin que haya ocurrido realmente. Esto rompe la integridad del dato.
- La solución: encapsular el contador y exponer acceso controlado con métodos.
¿Cuándo usar un guion bajo y cuándo dos?
Python ofrece dos niveles de señalización para atributos internos.
¿Qué significa un solo guion bajo?
- Un solo guion bajo (por ejemplo, _veces_prestado) es una convención: indica “no toques esto desde fuera”.
- Aun así, es accesible externamente. Sirve como recordatorio, no como barrera real.
¿Qué hace el doble guion bajo?
- Con doble guion bajo (__veces_prestado) se activa el name mangling: no podrás acceder directamente desde fuera del objeto.
- Si intentas leer o modificar ese atributo desde fuera, obtendrás un error: el mensaje indica que el atributo es interno y debe manejarse dentro de la clase.
¿Cómo implementar getters y setters con validaciones?
Para exponer datos de forma segura, crea un getter para leer y un setter para modificar con validaciones. Además, ajusta métodos como prestar y espopular para mantener coherencia.
class Libro:
def __init__(self, titulo, veces_prestado=0, disponible=True): # *init*
self.titulo = titulo
self.__veces_prestado = veces_prestado
self.disponible = disponible
def prestar(self):
if self.disponible:
self.__veces_prestado += 1
self.disponible = False
return f"Prestado exitosamente. Total préstamos: {self.__veces_prestado}."
else:
return "No está disponible." # evita None
def espopular(self):
return self.__veces_prestado > 5
def get_veces_prestado(self): # *getter*
return self.__veces_prestado
def set_veces_prestado(self, veces): # *setter*
# Aquí podrías validar orígenes confiables o rangos permitidos.
self.__veces_prestado = veces
¿Qué habilidades y conceptos prácticos se aplican?
- Diseño con programación orientada a objetos: clases, métodos y atributos.
- Control de acceso con atributos privados y convención de guiones bajos.
- Implementación de getter y setter para validar lectura y escritura.
- Manejo de estados: disponible/no disponible para evitar retornos inesperados como None.
- Lógica de negocio con espopular para medir uso real (> 5 préstamos).
- Criterios de encapsulación: “¿Debe un usuario externo modificar esta variable interna?” Si no, hazla privada y expón métodos con validaciones.
¿Te gustaría compartir cómo encapsularías otros atributos críticos de tu proyecto y qué validaciones agregarías en tus setters?