Partage
  • Partager sur Facebook
  • Partager sur Twitter

Les propriétés

Difficultés à comprendre le concept

Sujet résolu
    27 août 2014 à 18:50:54

    Bonjours,

    Régulièrement je suis le cours sur python disponible sur le site. Et je suis arrivé au chapitre sur les propriétés qui me pose quelque difficultés de compréhension.

    Je cite les points que je ne comprend pas :

    class Personne:
        """Classe définissant une personne caractérisée par :
        - son nom ;
        - son prénom ;
        - son âge ;
        - son lieu de résidence"""
    
        
        def __init__(self, nom, prenom):
            """Constructeur de notre classe"""
            self.nom = nom
            self.prenom = prenom
            self.age = 33
            self._lieu_residence = "Paris" # Notez le souligné _ devant le nom
        def _get_lieu_residence(self):
        """Méthode qui sera appelée quand on souhaitera accéder en lecture
            à l'attribut 'lieu_residence'"""
            
            
            print("On accède à l'attribut lieu_residence !")
            return self._lieu_residence
        def _set_lieu_residence(self, nouvelle_residence):
            """Méthode appelée quand on souhaite modifier le lieu de résidence"""
            print("Attention, il semble que {} déménage à {}.".format( \
                    self.prenom, nouvelle_residence))
            self._lieu_residence = nouvelle_residence
        # On va dire à Python que notre attribut lieu_residence pointe vers une
        # propriété
        lieu_residence = property(_get_lieu_residence, _set_lieu_residence)

    Dans cette partie du cours on nous montre une classe avec un attribut accessible uniquement via un accesseur ou modifiable uniquement avec un mutateur (du moins par convention d'après ce que j'ai compris).
    Or l'auteur nous dit : 

    <cite>proxile</cite> : Quand on veut accéder à objet.lieu_residence, Python tombe sur une propriété redirigeant vers la méthode_get_lieu_residence. Quand on souhaite modifier la valeur de l'attribut, en écrivant objet.lieu_residence = valeur, Python appelle la méthode _set_lieu_residence en lui passant en paramètre la nouvelle valeur.

    • D'abord on accéde à l'attribut sans le _ devant lieu alors que l'attribut avait été nommé _lieu_residence chose que je ne comprend pas.
    • Ensuite dans le cours il est dit que ces attributs avec un _ on n'y accéde pas en dehors de la classe (par convention) hors c'est exactement ce qui est fait pour moi.
    Dans mon esprit, les mutateurs et les accesseurs sont juste des méthodes qui seront appelées automatiquement lorsque l'on veut acceder ou modifier des attributs avec un _ devant. Ai-je tort de voir les choses ainsi ?

    De plus dans son exemple un seul attribut est privé, comment faire avec plusieurs attributs privés ?



    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      27 août 2014 à 19:55:14

      En python la responsabilité va souvent aux programmeurs. Dans ce contexte, accesseur et mutateur sont très souvent inutiles...

      Ces conseils sont pour Java et C++, pas de chance, pas pour python où l'on trouve que c'est une mauvaise manière de penser

      • Partager sur Facebook
      • Partager sur Twitter
        27 août 2014 à 20:39:27

        Mais il sont tout de même utiles pour executer un code lors de l'appel ou la modificaion d'un attribut ?
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          27 août 2014 à 21:06:59

          @ronlat, non ça l'est pas, ou j'ai pas compris, dans ce cas donne moi un exemple de son intérêt
          • Partager sur Facebook
          • Partager sur Twitter
            27 août 2014 à 23:38:44

            Je ne suis pas du tout un spécialiste de la question, mais prenons l'exemple d'un jeu où on possède disons un canon. À ce canon, on associe deux images différentes, selon que son état soit chargé ou dechargé. À chaque fois que son nombre de charges est modifié, on aimerait adapter l'attribut self.image à l'attribut self.charges, sans pour autant qu'on puisse changer l'image en dehors du code de la classe. Qui plus est, le nombre de charges du canon peut être modifié à plein d'endroits différents du programme. Dans ce cas, il peut être judicieux d'utiliser un mutateur.

            J'en conviens bien cependant, il est, me semble-t-il, toujours possible de traiter le problème autrement. Mais utiliser des accesseurs et des mutateurs peut dans certains cas clarifier un code ou plus pratiquement, résoudre plus simplement et efficacement un problème.

            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              28 août 2014 à 0:11:53

              @Mustiwa, je veux bien un code exemple plutôt...

              J'en conviens bien cependant, il est, me semble-t-il, toujours possible de traiter le problème autrement.

              Voilà tu as compris, on fait avec la philosophie du langage, et non une construction dont on a eu l'habitude dans un autre langage.

              • Partager sur Facebook
              • Partager sur Twitter
                28 août 2014 à 1:35:53

                Ok merci a vous c'est plus clair dans mon esprit :) ! (Bien qu'encore un peu flou).

                oldProgrammer a écrit:

                @ronlat, non ça l'est pas, ou j'ai pas compris, dans ce cas donne moi un exemple de son intérêt

                Bah il y avait un exemple dans le premier post mais sans réel intérêt, (on signaler juste quand on appelait/modifiait l'attribut).

                Mais l'exemple du canon est très judicieux, merci à @Mustiwa !

                • Partager sur Facebook
                • Partager sur Twitter
                  28 août 2014 à 10:17:48

                  Pour moi, une propriétés c'est comme un décorateur: c'est un objet qu'on utilise quand on a des années d'expériences en python, et qu'on peut vraiment comprendre la subtilité d'utiliser ce genre d'outils.

                  Si t'es encore en apprentissage (comme je le suis), te prends pas la tête avec ce genre de choses qui sont, à mon sens, du sucre syntaxique. Ça ne t'empêchera ABSOLUMENT pas de faire de BEAUX petits codes, PROPRES et FONCTIONNELS :lol:

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Précepte: Le mieux est l'ennemi du bien
                  Anonyme
                    28 août 2014 à 11:47:16

                    À chaque fois que son nombre de charges est modifié, on aimerait adapter l'attribut self.image à l'attribut self.charges, sans pour autant qu'on puisse changer l'image en dehors du code de la classe

                    Pour cela on surcharge les méthodes spéciales __setattr__ et __getattr__, c'est plus propre, car partie intégrante des méthodes d'une classe

                    Imaginons que je souhaite créer un objet Constante, voilà ce que ça donnera

                    class Constante:
                        def __init__(self, value=None):
                            self.value = value
                        
                        def __setattr__(self, var, val):
                            if var in self.__dict__ and self.value != None:
                                raise AttributeError ("Impossible de modifier une constante")
                            self.__dict__[var] = val
                                
                        def __getattr__(self, var):
                            return self.__dict__[var]
                    
                    c = Constante()
                    c.value = 12
                    
                    print(c.value) # 12 car value était à None précédemment
                    
                    c.value = 15 # Impossible de modifier une constante
                    


                    On travaille avec les fonctionnalités internes au langage, c'est plus propre et fonctionnel. Surtout c'est plus lisible, mais faut-il comme le dit Olygrim que le langage soit bien maîtrisé.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      28 août 2014 à 13:29:00

                      Je suis tout à fait d'accord, les méthodes setattr et getattr sont tout à fait adaptées, c'est pour cela que j'ai mentionné le fait qu'on peut résoudre ce genre de problèmes autrement. C'était simplement un exemple dans lequel l'utilisation des accesseurs et mutateurs pouvaient être justifiées ^^

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Les propriétés

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                      • Editeur
                      • Markdown