Los decoradores @property en Python convierten métodos en atributos accesibles con la anotación de punto, logrando interfaces limpias, validación y cálculo automático detrás de escena. Con un getter convertido en propiedad y un setter controlado, tu clase gana encapsulación efectiva sin cambiar cómo lees o escribes valores.
¿Qué es property y por qué hace tu código más pythonico?
Usar property permite exponer datos como atributos, pero con la lógica de métodos. Así, el acceso es natural y no requiere paréntesis, mientras mantienes el control interno.
Convierte un método en atributo de solo lectura con @property.
Controla la escritura con @nombre.setter y valida entradas.
Accede con la anotación de punto, sin paréntesis.
¿Cómo convertir un getter en propiedad con @property?
Primero, elimina el método get_... y declara la propiedad. Luego úsala como un atributo.
classLibro:def__init__(self, titulo, autor, ISBN): self.titulo = titulo
self.autor = autor
self.ISBN = ISBN
self._veces_prestado =0# parámetro interno@propertydefveces_prestado(self):return self._veces_prestado
En el flujo de impresión, en lugar de retornar solo el título desde libros_disponibles, retorna el objeto libro y accede así:
# en mainfor libro in libros_disponibles():print(libro.titulo, libro.veces_prestado)# sin paréntesis
¿Cómo controlar la escritura con setter y validación?
Con el setter defines cómo se asigna y validas valores. Si no cumple, genera un error claro.
classLibro:# ...@veces_prestado.setterdefveces_prestado(self, valor):if valor >0: self._veces_prestado = valor
else:raise ValueError("El valor de veces prestado debe ser mayor a cero")
Prueba en main asignando un valor negativo y ejecuta:
python main.py
Verás un ValueError con el mensaje de validación. Esto ayuda a detectar un bug antes de que llegue a usuarios reales.
¿Cómo usar properties para computar y mostrar datos?
Además de exponer valores, puedes crear propiedades que computan resultados a partir del estado interno. Por ejemplo, una propiedad es_popular basada en datos internos se accede como atributo y no necesita setter.
Propiedades computadas como es_popular evitan estados inconsistentes.
No declaras setter si no quieres permitir escritura.
Para mostrar información compuesta, crea una propiedad que devuelva una cadena con título, autor e ISBN.
classLibro:# ...@propertydefdescripcion_completa(self):returnf"{self.titulo} por {self.autor}{self.ISBN}"
Úsala en la salida en main con la anotación de punto:
print(libro.descripcion_completa)
¿Cómo se integra en main y biblioteca?
La integración es directa si retornas objetos libro en lugar de cadenas.
Modifica libros_disponibles para retornar la lista de objetos Libro.
Itera y accede a libro.titulo, libro.veces_prestado y libro.descripcion_completa.
Evita paréntesis: las propiedades se leen como atributos.
Ejecuta con python main.py para validar resultados.
¿Qué reto práctico puedes implementar ahora?
Pon en práctica las propiedades para reforzar encapsulación y claridad.
Agrega una propiedad nombre completo a la clase usuario que combine nombre y cédula.
Crea una propiedad en biblioteca para libros disponibles que retorne la lista de todos los libros disponibles.
Comparte tu implementación y comenta cómo validaste las asignaciones.
¿Tienes otra idea de propiedad útil en tu modelo de dominio? Cuéntala en los comentarios y qué validaciones agregarías.
Decoradores property en Python para atributos con validación