Bloc @numero.setter
Bonjour, danc ce cas précis, à quoi sert le bloc @numero.setter?
Le blocage de la valeur de l'attribut fonctionne déjà avec juste le getter @property, comme ceci:
class Compte:
def __init__(self, nom, numero, balance):
self.nom = nom
self._numero = numero
self.balance = balance
@property
def numero(self):
return self._numero
john = Compte(nom="John Smith", numero="123456", balance=20000)
Par ailleurs: pourquoi utiliser un underscore simple et non un double underscore dans ce cas?
Merci pour vos lumières!
Bonjour Simon,
L'underscore permet de signaler aux autres développeurs qu'il ne faut pas accéder directement à l'attribut depuis l'extérieur de la classe. On appelle ça rendre l'attribut privé.
Mais en réalité celui qui ne veut pas respecter peut y accéder quand même, car c'est juste une convention.
class Compte:
def __init__(self, nom, numero, balance):
self.nom = nom
self._numero = numero
self.balance = balance
@property
def numero(self):
return self._numero
@numero.setter
def numero(self, numero):
raise AttributeError("On ne change pas le numéro de compte !")
john = Compte(nom="John Smith", numero="123456", balance=20000)
print(john._numero)
Le double __ c'est autre chose : on appelle ça le name mangling. Python rend l'accès à l'attribut plus difficile en gros. Mais tu peux y accéder quand même comme tu peux le voir.
class Compte:
def __init__(self, nom, numero, balance):
self.nom = nom
self.__numero = numero
self.balance = balance
@property
def numero(self):
return self._numero
@numero.setter
def numero(self, numero):
raise AttributeError("On ne change pas de numéro de compte")
john = Compte(nom="John Smith", numero="123456", balance=20000)
Si tu fais ça tu as un attribute error :
print(john.__numero)
L'attribut est donc plus "difficile" d'accès, il faudrait en fait faire :
print(john._Compte__numero)
En résumé : que ça soit _ ou __ ça indique qu'il ne faut pas accéder à l'attribut en dehors de la classe.
Ce qui m'amène à dire que tu ne devrais pas modifier directement l'attribut, et donc passer par ce que l'on appelle un setter :
@numero.setter
def numero(self, numero):
raise AttributeError("On ne change pas de numéro de compte")
Ce qui est intéressant avec un setter c'est que tu peux mettre de multiples conditions. Avec un autre exemple :
class Personne:
def __init__(self, nom, age):
self.nom = nom
self._age = age
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if value < 0:
raise ValueError("L'âge ne peut pas être négatif")
else:
self._age = value
Tu dois procéder ainsi pour passer par le setter :
# Création de l'instance
personne = Personne("Patrick", 30)
# Modification avec le setter
personne.age = -5
# Lève ValueError: L'âge ne peut pas être négatif
J'ai pas été trop bavard ? lol
Le double underscore n'appprte aucune avantage concret par rapport au simple undercore. ac'est la raison pour laquelle la convension parmi les pythonistas est d'utiliser un simple underscore pour désigner un attribut privé.
Le setter sert souvent à implémenter une logique p.ex. de validation lors de l'affectation d'un valeur.
Inscris-toi
(c'est gratuit !)
Tu dois créer un compte pour participer aux discussions.
Créer un compte