En Python, le décorateur @property permet de créer des attributs "virtuels" — des méthodes qui apparaissent et sont utilisées comme des champs ordinaires, mais qui exécutent la logique du getter, setter ou deleter. C'est pratique pour créer des propriétés calculées ou contrôler l'accès aux données.
Exemple :
class Rectangle: def __init__(self, width, height): self._width = width self._height = height @property def area(self): return self._width * self._height @property def width(self): return self._width @width.setter def width(self, value): if value <= 0: raise ValueError('La largeur doit être positive') self._width = value r = Rectangle(3, 4) print(r.area) # 12 (appelée comme une propriété, pas une fonction) r.width = 10 # setter appelé automatiquement
Peut-on utiliser seulement un @property (méthode get), sans définir de setter ? Que se passera-t-il si l'on essaie de modifier cet attribut ?
Réponse : On peut définir seulement le getter @property sans setter (ni deleter). Cet attribut sera en lecture seule, toute tentative d'assignation déclenchera une AttributeError.
class C: @property def x(self): return 42 c = C() c.x = 99 # AttributeError: impossible de définir l'attribut
Histoire
On a essayé de sérialiser un objet à l'aide de la bibliothèque standard, en utilisant vars(obj) pour obtenir un dictionnaire des attributs. Il s'est avéré que les méthodes property n'étaient pas incluses dans la sortie de __dict__, leurs valeurs n'ont pas été sérialisées, ce qui a conduit à une fuite de données.
Histoire
Dans le projet, on a oublié d'ajouter un setter pour la property, du coup, toute tentative de modifier la valeur d'un champ calculé entraînait une erreur à l'exécution, bien que cela ait été anticipé dans la logique d'architecture.
Histoire
Dans le code en fonctionnement, le calcul de la valeur de la property permettait des opérations lourdes ou non sécurisées, qui étaient appelées de manière inattendue à chaque accès à la propriété. Cela a réduit les performances et a conduit à des appels bloquants dans le code multithreadé.