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?