Résolue

Exercice: Changer un attribut avec un méthode

# Orienté objet # Résolution d'erreurs # Tests unitaires

Hello!


Je ne comprends pas pourquoi mon code ci-dessous:


class Voiture:
    def __init__(self, marque, prix):
        self.marque = marque
        self.prix = prix
        
    def changer_prix(self, nouveau_prix):
        if not isinstance(nouveau_prix, int):
            raise TypeError('Seuls les nombres entiers sont acceptés')
        self.prix = nouveau_prix
        

voiture = Voiture(marque='Mazda', prix=30000)
voiture.changer_prix(35000)


ne permet pas de valider le test suivant (3e test):


voiture.prix = 35000
valeurs = ["bonjour", 1.5]

for valeur in valeurs:
    voiture.changer_prix(valeur)
    assert voiture.prix == 35000, "Votre script ne doit pas permettre de changer l'attribut prix pour autre chose qu'un nombre entier."


Merci d'avance pour vos explications.


David

Ici tu es dans une parfait exemple de protection d'attribut de classe et de setter. Dans l'exemple ci dessous tu verras que le décorateur @property permet de protéger le prix. 

En gros, en dehors de la classe tu ne peux pas changer le prix sans passer par le setter. Tu pourrais bien sûr modifier l'attribut _prix. Mais par convention cela est interdit de modifier un attribut avec un "_". Le décorateur @prix.setter te permet de controler avec ton assert ce que le user met à jour.


 class Voiture:
    def __init__(self, marque, prix):
      self.marque = marque
      self._prix = prix

    @property  
    def prix(self):
      return self._prix

    @prix.setter
    def prix(self, nouveau_prix):
      if not isinstance(nouveau_prix, int):
        raise TypeError('Seuls les nombres entiers sont acceptés')
      self._prix = nouveau_prix

      return None


In [3]: voiture = Voiture(marque="Mazda", prix=30000)

In [4]: voiture.prix
Out[4]: 30000
In [5]: voiture.prix = "lambo"
---------------------------------------------------------------------------
TypeError                 Traceback (most recent call last)
Input In [5], in <module>
----> 1 voiture.prix = "lambo"
File ~/Documents/pacdev/docstring_fr/q_r/test_att.py:13, in Voiture.prix(self, nouveau_prix)
   10 @prix.setter
   11 def prix(self, nouveau_prix):
   12   if not isinstance(nouveau_prix, int):
---> 13     raise TypeError('Seuls les nombres entiers sont acceptés')
   14   self._prix = nouveau_prix
   16   return None
TypeError: Seuls les nombres entiers sont acceptés

In [6]: voiture.prix = 2500
In [7]: voiture.prix
Out[7]: 2500


La protection d'attribut et les setter sont des notions importantes en POO. On peut en parler en mentorat si tu le souhaites.


N'hésites pas si ce n'est pas clair.

Salut P-A.

Merci beaucoup pour ta réponse très claire avec le code! 🙂

Bien que ton explication et ton exemple soient très clairs et parfaitement compréhensible pour moi, ça reste tout de même un concept que je n’ai jamais été amené à utiliser et que je ne maîtrise pas.


Donc, si on peut faire une passe dessus lors d’un mentorat, je suis carrément preneur !!!


Encore merci pour ton aide.

Salut David,


merci pour ton retour. Pas de souci. J'avoue que la réponse ne répond pas exactement à ta question mais c'est pour la bonne pratique pour protéger les attributs comme tu souhaitais le faire. Ok c'est noté pour un prochain mentorat.


A bientôt.

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.