IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Utilité des accesseurs et mutateurs [Python 3.X]


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Consultant fonctionnel
    Inscrit en
    Décembre 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant fonctionnel
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2014
    Messages : 5
    Par défaut Utilité des accesseurs et mutateurs
    Bonjour à tous,

    Débutant sur Python, je tente de comprendre certains principes dont celui de l'encapsulation.
    En Python on peut mettre un attribut semi privé en mettant un underscore devant.
    Puis on peut créer un accesseur et un mutateur avec le décorateur property.

    Ma question est de savoir par conséquent quelle est l'utilité de faire ca ? Si on a mis l'attribut en privé c'est justement pour ne pas pouvoir y accéder ou le modifier..?
    Grace aux propriétés on peut faire les deux sans problèmes.

    Quelqu'un aurait il un exemple d'utilité svp ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    class Point:
     
        def __init__(self, x, y):
            self._x = x
            self._y = y
     
        def get_x(self):
            return self._x
        def get_y(self):
            return self._y
        def set_x(self, x):
            self._x = x
        def set_y(self, y):
            self._y = y
     
        x = property(get_x, set_x)
        y = property(get_y, set_y)
    Merci

    Cdt

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 695
    Par défaut
    Salut,

    Citation Envoyé par Srn91 Voir le message
    Débutant sur Python, je tente de comprendre certains principes dont celui de l'encapsulation.
    En Python on peut mettre un attribut semi privé en mettant un underscore devant.
    Puis on peut créer un accesseur et un mutateur avec le décorateur property.

    Ma question est de savoir par conséquent quelle est l'utilité de faire ca ? Si on a mis l'attribut en privé c'est justement pour ne pas pouvoir y accéder ou le modifier..?
    Votre question n'est pas spécifique à Python, mais à la POO en général... et ne concerne pas l'écriture du code mais sa maintenance (comment faire évoluer une partie du code en évitant de casser les autres parties qui l'utilisent).
    En POO, on a des classes qui définissent attributs et méthodes. Certains seront "public": vous pouvez les utilisez. Certains seront "privés": vous ne devriez pas pouvoir les utiliser. Cette dernière interdiction est difficile à réaliser avec Python, on se contente de la convention '_'.

    La différence entre attribut et méthode se situe au niveau des accès qui sont de la forme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a.x = 2  # attribut
    a.set_x(2) # setter, méthode
    In fine çà fait la même chose: assigner la valeur 2 à l'attribut/membre "x"....
    Mais avec le temps, s'il faut vérifier que x est bien un entier dans l'intervalle 0..9, ce que fait l'appel à la fonction a.set_x pourra être changé sans que l'appelant ait à être modifié. C'est la raison pour laquelle des langages comme Java ou C++ recommandent setter/getter plutôt qu'un accès direct aux membres. Avec les "property" (ou plutôt les descriptors), Python permet de préserver cette interface tout en provoquant l'appel d'une fonction.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre émérite

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 662
    Par défaut
    Salut,

    L'intérêt principal des propriétés est de faire passer une méthode pour un attribut. De cette façon, on peut exécuter du code avant ou après l'accès ou l'écriture d'une valeur (comme vérifier son intégrité ou tout simplement la calculer).

    Autre exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class Square(object):
        def __init__(self, length):
            self.length = length
     
        def get_area(self):
            return self.length * self.length
     
        @property
        def area(self):
            return self.length * self.length
     
    obj = Square(2)
    print(obj.get_square())
    >>> 4
    print(obj.square)
    >>> 4
    On voit ici que l'intérêt (minime dans ce cas de figure) est d'éviter de faire appel à une méthode 'get_quelquechose' assez moche. Faire directement '.quelquechose' est des fois plus élégant.
    A noter que j'aurais très bien pu ajouter un attribut "privé" self._square à la classe, mais ce n'est pas indispensable. A noter aussi qu'il manque pour bien faire une méthode pour assigner une valeur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        @square.setter
        def square(self, value):
            if value <= 0:
                raire Exception('Square area must be stritcly positive')
            self.length = value ** 0.5
    J

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Consultant fonctionnel
    Inscrit en
    Décembre 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant fonctionnel
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2014
    Messages : 5
    Par défaut
    Merci à vous 2 pour vos réponses.

    @Julien N:
    Ton bout de phrase était vraiment ce que je recherchais "on peut exécuter du code avant ou après l'accès ou l'écriture d'une valeur".
    Du coup je vois l'intérêt de faire ces méthodes tout de même pour faire un contrôle de la valeur ou même demander à l'utilisateur de confirmer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    class Point:
     
        def __init__(self, x, y):
            self._x = x
            self._y = y
     
        def get_x(self):
            return self._x
        def get_y(self):
            return self._y
        def set_x(self, x):
            confirm = input("Vous aller modifier un attribut privé, veuillez confirmer (y/n):"
            if( confirm == 'y') :
                  self._x = x
        def set_y(self, y):
            confirm = input("Vous aller modifier un attribut privé, veuillez confirmer (y/n):"
            if( confirm == 'y') :
                  self._y = y
     
        x = property(get_x, set_x)
        y = property(get_y, set_y)

    @witricks:
    Justement en C++, l'intérêt des accesseurs et mutateurs est très clair. Lorsqu'on met une variable private, on ne peut ni y accéder ni la modifier directement. Cependant, ca force l'utilisateur à utiliser un accesseur ou mutateur en écrivant un code spécifique qui montre bien qu'on veut accéder un truc privé :
    monObjet.set_attribut(nouvelleValeur)

    Alors qu'en Python, méme si on déclare l'attribut privé, bah les property permettent d'y accéder et de le modifier de la même manière que s'il était public :
    monObjet.attribut = 3


    Par conséquent j'ai une autre question, peut être pourriez vous y répondre sans que je fasse un autre topic.
    Quelle est l'utilité de faire un attribut semi-privé ( en utilisant juste la convention du underscore ), plutôt que de faire un vrai attribut privé (en utilisant les doubles underscores ) inaccessible depuis l'extérieur de la classe ?

    Merci pour votre aide

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 695
    Par défaut
    Citation Envoyé par Srn91 Voir le message
    Alors qu'en Python, méme si on déclare l'attribut privé, bah les property permettent d'y accéder et de le modifier de la même manière que s'il était public :
    monObjet.attribut = 3
    Il suffit de tester pour s'assurer que ce n'est pas le cas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> class A:
    ...    @property
    ...    def __x(self):
    ...        return 'get x'
    ...
    >>> A().__x
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: A instance has no attribute '__x'
    >>>
    Citation Envoyé par Srn91 Voir le message
    Par conséquent j'ai une autre question, peut être pourriez vous y répondre sans que je fasse un autre topic.
    Quelle est l'utilité de faire un attribut semi-privé ( en utilisant juste la convention du underscore ), plutôt que de faire un vrai attribut privé (en utilisant les doubles underscores ) inaccessible depuis l'extérieur de la classe ?
    L'intérêt d'un attribut privé est qu'il ne pourra pas être surchargé facilement par une s/classe. Voir l'exemple donné dans le Python tutorial... ou tester soi-même:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    >>> class A:
    ...     __x = 'from A'
    ...     def show(self):
    ...         print (self.__x)
    ...
    >>> class B(A):
    ...     __x = 'from B'
    ...     def show(self):
    ...         print (self.__x)
    ...         super().show()
    ...
    >>> B().show()
    from B
    from A
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    >>> class A:
    ...     x = 'from A'
    ...     def show(self):
    ...         print (self.x)
    ...
    >>> class B(A):
    ...     x = 'from B'
    ...     def show(self):
    ...         print (self.x)
    ...         super().show()
    ...
    >>> B().show()
    from B
    from B
    >>>
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Consultant fonctionnel
    Inscrit en
    Décembre 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant fonctionnel
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2014
    Messages : 5
    Par défaut
    J'ai pas bien saisi le sens de ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> class A:
    ...    @property
    ...    def __x(self):
    ...        return 'get x'
    ...
    >>> A().__x
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: A instance has no attribute '__x'
    >>>
    En faite ce que je voulais dire c'est que même si on met un attribut privé, les property permettent un accés en lecture écriture directe sans que l'utilisateur ne s'en rende compte. Je pensais à un code comme ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class A:
     
        def __init__(self,x):
            self.__x = x
     
        @property
        def x(self):
            return self.__x
        @x.setter
        def x(self,x):
            self.__x = x
     
    a = A(3)
    print(a.x) # lecture direct a lattribut prive
    a.x = 5 # ecriture direct sur lattribut prive
    print(a.x)
    ... qui affiche :
    Mais du coup c'est bon, je comprends que faire une méthode ca permet de rajouter du code lors de l'écriture/lecture.
    Et merci pour l'exemple d'utilisation en héritage !

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 695
    Par défaut
    Citation Envoyé par Srn91 Voir le message
    En faite ce que je voulais dire c'est que même si on met un attribut privé, les property permettent un accés en lecture écriture directe sans que l'utilisateur ne s'en rende compte.
    L'attribut que présente la property est "x". Celui auquel accède la fonction associée est "__x" mais il pourrait s'appeler "toto" ou "a.b.xyz" tant que la fonction/méthode peut y accéder... ce sera toujours transparent pour l'utilisateur qui lui ne verra que "x".

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Utilité des accesseurs 'simplifiés' ?
    Par Marauder dans le forum C#
    Réponses: 3
    Dernier message: 29/06/2016, 16h44
  2. Ambiguïté concernant l'utilité des accesseurs
    Par phenomeno dans le forum Général Java
    Réponses: 7
    Dernier message: 21/09/2009, 20h35
  3. Utilité des schemas sous Postgresql?
    Par sessime dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 18/03/2005, 15h45
  4. Utilité des logos Xiti ?
    Par KibitO dans le forum Evolutions du club
    Réponses: 5
    Dernier message: 20/02/2005, 17h42
  5. utilité des DbControl
    Par portu dans le forum Bases de données
    Réponses: 6
    Dernier message: 02/07/2004, 05h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo