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