Un objeto bien diseñado PROTEGE sus datos: no deja que cualquiera ponga un saldo negativo o un valor
inválido. Eso es la ENCAPSULACIÓN. Y a veces quieres exponer un valor que se CALCULA (el total con IVA, que
depende del valor) como si fuera un atributo normal, sin paréntesis. Para ambas cosas, Python tiene una
herramienta elegante: @property. Hoy aprendes a proteger y a calcular con propiedades —el toque
profesional en el diseño de clases—.
La cocina y el menú
La convención de lo "privado"
@property: atributos calculados y validados
@property convierte un método en un atributo de solo lectura: g.valor (sin paréntesis) llama al método
valor() pero se usa como si fuera un dato. Con @valor.setter agregas la lógica de asignación: g.valor = 5000
pasa por el setter, que puede VALIDAR (aquí rechaza negativos). Y con_iva es una propiedad CALCULADA: no se
guarda, se deriva de _valor cada vez que la pides —siempre coherente, imposible de desincronizar—. Es lo
mismo que "lo derivado se calcula, no se guarda" que viste en React (SC-06), aplicado a objetos.
¿Qué permite @property y qué ventaja tiene sobre un atributo normal?
Mini-reto
Protege una Cuenta de Mi Bolsillo: 1) guarda el saldo como _saldo (interno) e inicialízalo en
__init__; 2) expón saldo con @property (getter) y un setter que RECHACE valores negativos con
ValueError; 3) agrega una propiedad calculada saldo_con_bono que devuelva el saldo × 1.05; 4) crea una
cuenta, lee saldo y saldo_con_bono, asigna un saldo válido, e intenta uno negativo para ver la
validación. Nota que saldo_con_bono se recalcula solo.
Qué sigue
Ya proteges y calculas con properties. La última lección del módulo trae dos joyas modernas: las
DATACLASSES (que generan __init__, __repr__ y __eq__ por ti, eliminando código repetitivo) y los
PROTOCOLS (el "duck typing" tipado, primo del tipado estructural de TypeScript). El toque final para
escribir POO pythónica y elegante.