Encapsulamiento

El decorador @property


Python ofrece una forma elegante de controlar el acceso a los atributos mediante el decorador @property. Este permite definir métodos que se comportan como atributos, haciendo posible realizar acciones al acceder, modificar o eliminar un valor, sin cambiar la sintaxis para el usuario.

Ejemplo: uso de @property
class CuentaBancaria:
    def __init__(self, titular, saldo):
        self.titular = titular
        self.__saldo = saldo  # Atributo privado

    @property
    def saldo(self):
        # Método que se comporta como un atributo
        print("Consultando saldo...")
        return self.__saldo

cuenta = CuentaBancaria("Carlos", 5000)
print(cuenta.saldo)  # Se accede como si fuera un atributo
print(cuenta.saldo)  # Se accede como si fuera un atributo

Observa que no usamos paréntesis () al acceder a cuenta.saldo, aunque internamente es un método.


¿Por qué es útil esto?

  • Podemos validar o calcular dinámicamente el valor antes de devolverlo.
  • Podemos proteger atributos que no deben ser modificados libremente.
  • Podemos cambiar la implementación interna sin afectar al código que usa la clase.

Modificación controlada: @<nombre>.setter

Si también deseamos permitir la modificación del atributo, podemos definir un setter con el decorador @<nombre>.setter:

class CuentaBancaria:
    def __init__(self, titular, saldo):
        self.titular = titular
        self.__saldo = saldo

    @property
    def saldo(self):
        return self.__saldo

    @saldo.setter
    def saldo(self, nuevo_saldo):
        if nuevo_saldo >= 0:
            self.__saldo = nuevo_saldo
        else:
            print("No se puede establecer un saldo negativo.")

cuenta = CuentaBancaria("Carlos", 5000)
cuenta.saldo = 3000  # Invoca al setter
print(cuenta.saldo)  # Invoca al getter