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 :

Les "descriptor" (suite des "decorator")


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Par défaut Les "descriptor" (suite des "decorator")
    Vu qu'on a parlé juste avant des "décorator". Je fais ici un tout petit message pour donner un exemple sur les "descriptor", assez méconnu aussi.

    http://www.developpez.net/forums/d68...urs-quoi-sert/


    Les "descriptor" permettent de déclarer un attribut de classe sur lesquels on peut aussi effectuer des contrôles. C'est un peu l'équivalent des "decorator" mais pour les attributs.

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
     
    from types import *
     
    class MyIntProperty(object):
        def __init__(self, initval=None):
            self.val = 0
     
        def __get__(self, obj, objtype):
            return self.val
     
        def __set__(self, obj, val):
            self.val = self._isint(val)
     
        def _isint(self, val):
            if type(val) is not IntType:
                raise Exception('Parameter must be Int')
            else:
                return val
     
    class MyClass(object):
        x = MyIntProperty(10)
        y = MyIntProperty()
     
     
    test = MyClass()
    test.x, test.y = 10, 100
    print test.x, test.y
    test.x, test.y = 20, 'aa'
    print test.x, test.y

  2. #2
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    Merci DelphiManiac, je n'avais jamais pris la peine de comprendre les descripteurs.
    Mais cela me semble un peu redondant, pour contrôler l'accès aux attributs, avec les properties et/ou getattr/setattr, non ?
    (au passage: il est généralement préférable d'utiliser isinstance plutôt que type(..) = ... car ce dernier ne tient pas compte de l'héritage).

    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
    23
    24
    class MyClass2(object):
        __x = 0
        __y = 0
     
        def _isint(self, val):
            if not isinstance(val, int):
                raise Exception('Parameter must be Int')
            else:
                return val
     
        def __get(attr):
            return lambda self: getattr(self,attr)
     
        def __set(attr):
            return lambda self,val: setattr(self, attr, self._isint(val))
     
        x = property(__get("__x"), __set("__x"))
        y = property(__get("__y"), __set("__y"))
     
    test = MyClass2()
    test.x, test.y = 10, 100
    print test.x, test.y
    test.x, test.y = 20, 'aa'
    print test.x, test.y
    Enfin, c'est vrai que le code avec les descripteurs est peut-être un peu plus simple
    Mais pas tant que ça quand-même. Les descripteurs sont sans doute préférables s'il y a plusieurs attributs qui doivent avoir le même comportement (d'où ce petit 'détour' que j'ai du faire par getattr/setattr pour éviter la duplication de code), surtout s'ils se trouvent dans des classes différentes. S'il n'y en a qu'un, les properties me semblent plus simple.

    As-tu (ou qq'un d'autre) déjà eu l'occasion d'utiliser les descripteurs (pour autre chose que tester la fonctionnalité) ?

  3. #3
    Membre Expert
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Par défaut
    L'intérêt des descripteurs est, comme tu le sous entend, quand il faut mutualiser un comportement.

    Un exemple de cas ou cela pourrait être utile, c'est par exemple pour contrôler un droit d'accès à certaines propriétés.

    C'est un comportement générique qui peut s'appliquer à toutes les propriétés et être codé dans un descripteur.

  4. #4
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    bonjour,

    une petite chose m'échappe. Soit la classe suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class MyOtherClass(object):
        def __init__(self):
            self.x = MyIntProperty(10)
            self.y = MyIntProperty()
    L'instruction ci-dessous ne lève pas d'exception chez moi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    test=MyOtherClass()
    test.x, test.y = 20., 'aa'
    On dirait qu'on écrase la définition de self.x et self.y avec l'affectation au lieu d'appeler la méthode __set__ du descripteur. Est-ce voulu par le mécanisme des descripteurs ?

  5. #5
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    En fait, tu déclares x et y dpuis la methode __init__, ce qui a pour effet de creer des variable d'instance... or, les descripteur ne peuvent s'appliquer que sur les attributs de classes (autrement dit, la valeur de ces attribut sera partagé par toutes les instances...)
    essayes donc comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class MyOtherClass(object):
        x = MyIntProperty(10)
        y = MyIntProperty()
     
    test=MyOtherClass()
    test.x, test.y = 20., 'aa'

  6. #6
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    d'accord, donc c'est un mécanisme voulu par le descripteur de ne s'appliquer que sur les attributs de classe et non les variables d'instances.

    merci pour l'éclaircissement

Discussions similaires

  1. QGIS : lenteur pour afficher les listes des vues dans "Ajouter une table PostGIS"
    Par fafa63 dans le forum SIG : Système d'information Géographique
    Réponses: 2
    Dernier message: 11/07/2014, 19h04
  2. Select et insert avec des caracteres speciaux (quote ')
    Par Paco75 dans le forum Requêtes
    Réponses: 2
    Dernier message: 25/10/2006, 14h59
  3. Réponses: 2
    Dernier message: 19/07/2006, 00h12

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