Les propriétés (property) en Python sont apparues comme un moyen d'implémenter élégamment l'encapsulation des attributs, similaire aux getters et setters d'autres langages (Java/C++), mais sans avoir à appeler explicitement les méthodes. Avant property, l'accès aux variables devait être réalisé via des méthodes get/set explicites, ce qui compliquait et encombrait l'interface de la classe.
Le problème réside dans le fait que l'utilisateur de la classe dispose d'une interface transparente pour travailler avec les attributs (en utilisant la notation pointée obj.x), tandis que sous le capot, il est possible de contrôler la logique de calcul, de vérification, de mise en cache ou de validation des valeurs. Sans property, en cas de changement de l'implémentation interne, il est nécessaire de modifier tous les appels, ce qui entraîne de nombreuses erreurs et réduit l'extensibilité.
La solution — le décorateur @property permet de transformer une méthode en attribut, tout en cachant la logique de calcul, de vérification ou de chargement paresseux à l'intérieur des méthodes, sans changer l'interface externe de la classe. Le getter est accessible en lecture seule, tandis que .setter organise l'écriture, et .deleter — la suppression.
Exemple de code :
class Rectangle: def __init__(self, width, height): self._width = width self._height = height @property def area(self): # 'area' peut maintenant être lu comme un attribut return self._width * self._height @property def width(self): return self._width @width.setter def width(self, value): # appelé automatiquement lors de l'affectation rect.width = ... assert value > 0, "La largeur doit être positive" self._width = value rect = Rectangle(3, 4) print(rect.area) # 12 rect.width = 10 print(rect.area) # 40
Caractéristiques clés :
Une property peut-elle fonctionner avec des méthodes de classe ou des méthodes statiques ?
Non. property ne réalise que des propriétés au niveau des instances. Pour les propriétés au niveau de la classe, utilisez des descripteurs spéciaux ou @classmethod-property (à implémenter manuellement).
Si vous déclarez une property avec seulement un getter sans setter, pourra-t-on écrire dans l'attribut ?
Non. Une telle property est en lecture seule ; toute tentative d'affectation déclenchera un AttributeError.
Que se passe-t-il si une exception se produit dans le setter (par exemple, assert) ?
L'exception sera levée, l'affectation ne se produira pas et la valeur de l'attribut restera inchangée. C'est souvent utilisé pour la validation.
Cas négatif : Attributs publics de classe, modification sans contrôle.
Avantages : rapide, simple.
Inconvénients : on ne peut pas modifier la logique interne sans réécrire le code client, des états incohérents sont possibles.
Cas positif : Encapsulation via property, logique dans getter/setter, contrôles stricts.
Avantages : flexibilité, contrôle, transparence, évolution API sécurisée.
Inconvénients : un peu plus de code, complication légère lors du débogage.