Forum Programmation.python Python et les propriétés. property()

Posté par . Licence CC by-sa.
0
7
mar.
2016

Salut,

besoin d'un petit peu d'aide sur python3 et les propriétés.

En initialisant une variable je souhaite qu'elle soit de type propriété c'est à dire je souhaite que lorsque cette variable est modifiée une fonction me signale que je l'ai modifiée.

""" on définit un ingrédient """
class ingredient():
    def __init__(self):
        """ on initialise les attributs de notre objet """
        self._commercant = ""

    def _set_commercant(self,nom):
        """ on veut juste un mutateur """
        """ lors de la création de l'entrée du commercant """
        print("Vous avez modifié l'entrée du commercant §")
        self._commercant = nom

    commercant = property(None,_set_commercant)

Je n'ai pas trouvé comment utiliser property en laissant l'accesseur par défaut :(.

Et sauriez-vous si on éxécute ce code ne devrait on pas logiquement boucler puisque lors de l'éxécution de la méthode --init-- on mutte sur _self._commercant ?

Enfin, la convention serait que la porté d'un accesseur, un mutateur, del ou help soit restreinte a l'intérieur de la ou il est appelé mais ce n'est pas obligatoire. Peut on configurer l'interpréteur dans cette configuration afin d'être sur que python n'accède pas via propriety ailleur dans le code ?

Je n'ai pas trouvé de référence dans la Pep concernant cette "convention" je ne sais donc que peu à ce sujet.

Merci de votre attention, si vous avez des idées je suis preneur.

  • # properties

    Posté par (page perso) . Évalué à 3.

    Bonjour,

    en Python, les attributs d'objet sont totalement dynamiques, sauf -disons- les propriétés, en effet (pour bien comprendre, je conseille de jeter un œil plus tard à setattr et __setattr.
    Je ne vois pas de problème dans le init puisqu'il met en place self._commercant, et non self.commercant.
    La property gagnerait à être définie ainsi :

    commercant = property(fset=_set_commercant)

    Utiliser les arguments nommés plutôt que positionnel !

    Je ne suis pas sûr de comprendre la question, mais on ne peut pas vraiment être sûr que quelqu'un n'accède pas à un attribut depuis un autre endroit du code en Python.

    • [^] # Re: properties

      Posté par . Évalué à -4.

      Merci pour ces remarques.

      Effectivement il n'y a aucun bug dans l'init. J'avais mal compris le principe des propriétés car je n'y était pas familiarisé. Ca va déjà mieux avec ces explications.

      Concernant le fait d'accéder a un autre endroit c'était par rapport aux convention dont j'ai entendu parlé du coup je pensais être obligé de manipuler un attribut a l'intérieur de mon objet tout au plus ce qui m'aurai obligé à penser mon code différemment.

  • # Pas de défaut…

    Posté par (page perso) . Évalué à 2.

    Je n'ai pas trouvé comment utiliser property en laissant l'accesseur par défaut :(.

    S'il en manque une des méthodes d'accès, Python n'a aucun moyen de connaître les moyens d'accès / calcul pour la propriété désirée. Il peut ne pas y avoir de variable derrière, ou bien plusieurs, donc le "défaut" n'a pas de sens. D'ailleurs, en mettant juste un getter ou juste un setter, tu peux faire une propriété en lecture seule ou en écriture seule.

    Mais rien n'empêche l'accès direct à un éventuel attribut sous-jacent _xxx. Même un nommage en __xxx, qui est réécrit en _Classe__xxx par Python, permet l'accès via ce nom.

    In[5]: class C:
    ...         def __init__(self):
    ...             self.x = 1
    ...             self._y = 2
    ...             self.__z = 3
    ...             
    In[6]: c = C()
    In[7]: c.x
    Out[7]: 1
    In[8]: c._y
    Out[8]: 2
    In[9]: c._C__z
    Out[9]: 3

    Python 3 - Apprendre à programmer en Python avec PyZo et Jupyter Notebook → https://www.dunod.com/sciences-techniques/python-3

  • # ...

    Posté par (page perso) . Évalué à 3.

    Il n'y a pas d'accesseur par défaut, rien ne permet de dire que self.commercant (la property) doit renvoyer self._commercant (une variable classique), donc c'est à toi de le faire (better explicit …). C'est pour ca aussi que tu ne risque pas de boucle infinie, quand tu set self._commercant ça n'appelle pas la property.
    Et au passage autant utiliser la syntaxe avec les décorateurs, c'est fait pour :

    class ingredient():
        def __init__(self):
            self._commercant = ""
    
        @property
        def commercant(self):
            return self._commercant
    
        @commercant.setter
        def commercant(self, nom):
            print("Vous avez modifié l'entrée du commercant §")
            self._commercant = nom

    Peut on configurer l'interpréteur dans cette configuration afin d'être sur que python n'accède pas via propriety ailleur dans le code ?

    self._commercant est une variable privée mais comme beaucoup de choses en Python c'est une convention. Rien n'empêche d'y accéder (i = ingredient() ; i._commercant = 'foo'), c'est juste mal de le faire.

    • [^] # Re: ...

      Posté par . Évalué à -4.

      Curieux que python qui a une réputaiton d'être un langage "stricte" puisse être aussi flexible en pratique.

      Je m'attendais pas a autant de relativité plutot à un extrait de la PEP.

      Et donc je découvre les décorateurs en chèquant ton code et je trouve ca sublime, je vais essayer d'intégrer cette forme qui est très estétique.

      Décidément on ne cesse de s'enrichir, merci.

  • # Java

    Posté par . Évalué à 1.

    Bonjour, merci pour les informations. Mais personnellement, j’ai appris le Java et le résultat n’est pas le même. Parce qu’en consultant les commentaires, les méthodes pour y procéder sont identiques mais au niveau des résultats, ce ne sont pas les mêmes.

  • # Commentaire supprimé

    Posté par . Évalué à 0. Dernière modification le 12/04/16 à 21:22.

    Ce commentaire a été supprimé par l'équipe de modération.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.