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 :

Descripteur et valeur des attributs pour les instances


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 23
    Points : 16
    Points
    16
    Par défaut Descripteur et valeur des attributs pour les instances
    bonjour à tous

    ma question prote sur les "bonnes manières" avec les descripteurs ( __get__ & __set__ )

    j'utilise les descripteurs en temps qu'attribut de classe, pour conformer/valider les valeurs
    la déclaration de mes objets "Model" ressemble un peu au Model de Django ( déclarative ), avec un objectif légèrement différent.

    pour la sauvegarde la valeur filtré par mon descripteur, pour chaque instance :

    méthode 1 : mon descripteur contient un dictionnaire d'instance de mon model et la valeur de mon attribut pour cette instance

    méthode 2 : j'utilise une variable avec un nom 'masqué' modifié dans mon instance pour garder la valeur

    méthode 3 : j'instancie chacun de mes descripteurs

    méthode 4 : votre proposition ^^

    merci de votre aide


    Stéphane

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    En gros on a l'ensemble suivant:
    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
    class entity(type):
         ...
    class Entity(metaclass=entity):
         ...
    class descriptor:
        name = None
        def __init__(self, ...):
            ....
        def __get__(self, instance, class_):
             ...
        def __set__(self, instance, value):
             ...
    class User(Entity):
         a1 = descriptor(...)
         a2 = descriptor(...)
    Si on doit pouvoir associer des valeurs différentes à chaque instance User, il faudra les stocker quelque part et comme on a déjà le dict de l'instance pourquoi ne pas l'utiliser? Pour le "name", le __set__ permet d'utiliser "a1" sans by-passer l'assignation du descriptor côté classe.

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

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 23
    Points : 16
    Points
    16
    Par défaut
    Bonsoir wiztricks,

    " En gros on a l'ensemble suivant: ......"
    au nom de variable près, c'est exactement cela ^^. Au fond de moi, cela me rassure.

    "comme on a déjà le dict de l'instance pourquoi ne pas l'utiliser? "
    c'est ce que je supposé dans la deuxième approche

    La première méthode étant découverte dans le livre "Pro Python", mais avec une précision du style : "C'est pas le top ...... ", d'ou mon interrogation.


    en revanche, je décroche sur votre explication :
    "
    Pour le "name", le __set__ permet d'utiliser "a1" sans by-passer l'assignation du descriptor côté classe.
    "

    pour l'instant, je "masque" ma variable avec un nom du type :
    "__unnomquejesperequepersonneuntilsara_"+ attr_name
    que je getattr/setattr à mon instance

    je récupère, attr_name, le nom de l'attribut de classe, lors de sa découverte dans le __new__ en metaclass, mais tout cela ne ressemble pas à votre dernière explication.


    merci pour votre expertise,

    Stéphane

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,
    Citation Envoyé par 3DKermit Voir le message
    Pour le "name", le __set__ permet d'utiliser "a1" sans by-passer l'assignation du descriptor côté classe.
    C'est ce que dit la documentation:
    For instance bindings, the precedence of descriptor invocation depends on the which descriptor methods are defined. A descriptor can define any combination of __get__(), __set__() and __delete__(). If it does not define __get__(), then accessing the attribute will return the descriptor object itself unless there is a value in the object’s instance dictionary. If the descriptor defines __set__() and/or __delete__(), it is a data descriptor; if it defines neither, it is a non-data descriptor. Normally, data descriptors define both __get__() and __set__(), while non-data descriptors have just the __get__() method. Data descriptors with __set__() and __get__() defined always override a redefinition in an instance dictionary. In contrast, non-data descriptors can be overridden by instances.
    Testez et vérifier si çà fonctionne.

    pour l'instant, je "masque" ma variable avec un nom du type :
    "__unnomquejesperequepersonneuntilsara_"+ attr_name
    que je getattr/setattr à mon instance

    je récupère, attr_name, le nom de l'attribut de classe, lors de sa découverte dans le __new__ en metaclass, mais tout cela ne ressemble pas à votre dernière explication.
    La classe qui crée le descriptor aura attr_name dans son __dict__ et un nom dérivé dans le __dict__ des instances. Le nom dérivé étant "privé", çà complique l'accès à la "valeur" de l'attribut pour l'utilisateur. Mais l'utilisateur est supposé passer par un accès sur x.attr_name: quel est l'intérêt de "dériver" le nom (qu'on a déjà) en s'efforçant de cacher?

    Plus généralement, les descriptors permettent d'interposer une fonction sur le chemin d'accès aux attributs d'une classe ou d'une instance.
    Les paramètres de cette fonction seront l'instance du descriptor et les paramètres reçus par __get__, __set__ i.e. l'instance et/ou la class.

    Ecrivons access_fonction(self, instance, class_=None) où self sera l'instance du descriptor. Comme on devra pouvoir associer plusieurs descriptor à une même instance/class, il faut savoir qui associer à quoi: c'est le rôle du ".name" à récupérer dans "self".

    Avec ce .name, on peut "stocker" la valeur dans:
    1. le __dict__ d'instance ou
    2. un autre objet récupéré via un accès à un attribut d'"instance/class".


    Le cas (2) sera (nécessairement) plus coûteux que le cas (1).
    Et on peut souhaiter que la fonctionnalité qui motive le choix (2) méritera ce surcoût.

    Il n'est pas interdit de choisir (2) dans tous les cas.
    Fonctionnellement, c'est pareil. Mais on ne perd plus de temps à se poser des questions, réaliser des tests et des revues qualité spécifiques à chaque cas,...

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

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 23
    Points : 16
    Points
    16
    Par défaut
    salut,

    Citation Envoyé par wiztricks Voir le message

    Plus généralement, les descriptors permettent d'interposer une fonction sur le chemin d'accès aux attributs d'une classe ou d'une instance.
    Les paramètres de cette fonction seront l'instance du descriptor et les paramètres reçus par __get__, __set__ i.e. l'instance et/ou la class.
    J'AI COMPRIS !!!!!!!!!!!!!
    j'avoue, j'ai bien du relire une bonne dizaine de fois votre explication et la documentation

    en fait, dans mon implémentation, j'utiliser dans le __set__

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    setattr(instance, attr_name, value)
    qui me provoqué un jolie : "RuntimeError: maximum recursion depth exceeded"

    au lieu d'un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    instance.__dict__[attr_name] = value
    mon erreur était de croire que ces deux lignes sont équivalents


    merci pour votre expertise,
    ça me simplifie beaucoup le code


    Stéphane

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Citation Envoyé par 3DKermit Voir le message
    J'AI COMPRIS !!!!!!!!!!!!!
    j'avoue, j'ai bien du relire une bonne dizaine de fois votre explication et la documentation
    Oui, tout cela est un peu ardu.
    Je suis heureux que vous ayez appris quelque chose.
    - 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. [2012] Non respect des couleurs pour les instances 2008R2
    Par clementratel dans le forum Administration
    Réponses: 2
    Dernier message: 27/05/2013, 15h40
  2. [Plugin GMF] Récupération des attributs pour les réutiliser
    Par Jihane22 dans le forum Eclipse Modeling
    Réponses: 2
    Dernier message: 15/09/2010, 10h51
  3. Réponses: 8
    Dernier message: 13/10/2008, 20h26
  4. [DOM] changer les valeurs des attributs d'un fichier XML
    Par nonna dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 21/03/2008, 11h56
  5. [XSLT] Eliminer les doublons de valeurs des attributs
    Par furybubu dans le forum XSL/XSLT/XPATH
    Réponses: 9
    Dernier message: 04/05/2007, 10h09

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