Résolue

Bloc @numero.setter

# Méthodes # Orienté objet

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

Merci Gabriel d'avoir été bavard ! 😄C'est très clair, et je comprends beaucoup mieux l'intérêt du setter maintenant.

Thierry Chappuis

Mentor

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 !)

Inscris-toi

Tu dois créer un compte pour participer aux discussions.

Créer un compte

Rechercher sur le site

Formulaire de contact

Inscris-toi à Docstring

Pour commencer ton apprentissage.

Tu as déjà un compte ? Connecte-toi.