Qu'est-ce qu'une propriété en Python ?
Les propriétés permettent de définir des comportements de 'getter' et 'setter' sur les méthodes d'une classe.
Cela nous permet également d'appeler une méthode sans avoir besoin d'utiliser les parenthèses.
Pour créer une propriété de type get
, on utilise le décorateur @property
sur une méthode :
class CompteBancaire: @property def numero(self): return "83947382738" compte = CompteBancaire() # On peut accéder à la valeur retournée par la méthode numero sans utiliser les parenthèses print(compte.numero)
En l'état, notre propriété est en lecture seule. Comme nous n'avons pas défini de 'setter', il est impossible de modifier cet attribut :
class CompteBancaire: @property def numero(self): return "83947382738" compte = CompteBancaire() compte.numero = "123456789" # AttributeError: can't set attribute on line 24
Pour rajouter un 'setter', il faut décorer la méthode du même nom avec un décorateur avec la syntaxe @method.setter
:
class CompteBancaire: def __init__(self): self._numero = "83947382738" @property def numero(self): return self._numero @numero.setter def numero(self, value): self._numero = value compte = CompteBancaire() compte.numero = "123456789" print(compte.numero)
Dans ce cas, on utilise donc le décorateur @numero.setter
sur la méthode numero
.
Nous rajoutons également un attribut privé (self._numero
) qui n'est donc pas destiné à être manipulé directement.
Cela permet notamment de changer en interne le nom de notre attribut sans que cela impacte des utilisateurs potentiels de notre classe (on pourrait renommer self._numero
par self._identifiant
et laisser le nom des méthodes tel quel).
Le 'setter' nous permet également de rajouter un peu de logique lors de la modification d'un attribut.
Par exemple, nous pouvons vérifier si la nouvelle valeur donnée au numéro du compte ne contient que des nombres (et lever une erreur si ce n'est pas le cas) :
class CompteBancaire: def __init__(self): self._numero = "83947382738" @property def numero(self): return self._numero @numero.setter def numero(self, value): if value.isdigit(): self._numero = value else: raise ValueError("Le numéro du compte ne peut contenir que des chiffres.") compte = CompteBancaire() compte.numero = "123456789" # Fonctionne compte.numero = "abcdefghi" # ValueError