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

  1. #1
    Membre émérite
    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 : 60
    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
    Points : 2 533
    Points
    2 533
    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
    Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !

    On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.

  2. #2
    Membre expérimenté
    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
    Points : 1 384
    Points
    1 384
    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 émérite
    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 : 60
    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
    Points : 2 533
    Points
    2 533
    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.
    Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !

    On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.

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

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

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    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 éclairé
    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
    Points : 773
    Points
    773
    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 éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    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

  7. #7
    Membre éclairé
    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
    Points : 773
    Points
    773
    Par défaut
    Je voulais commencer à apprendre à me servir des métaclasses, et je suis tombé sur ce post :
    http://www.developpez.net/forums/d39...t/#post2433323

    Et j'ai trouvé que c'était sympatique comme manière de définir des properties...

    J'ai donc testé, et y'a une toute petite chose qui me fait préférer les descriptors aux properties, c'est le fait qu'on est pas obligé de passer par une instance pour acceder au contenu de la property (enfin, de façon courte j'entend):
    par exemple, en partant du principe que l'on a une classe Foo qui possède un descriptor x, on peut taper Foo.x et acceder au contenu de ce dernier (la méthode get est bien appelée) alors que si x était une property, la précédente commande me retournerait <porperty object blablabla...>. Mainteneant écrire un descriptor est assez lourd surtout si on en veut plusieurs qui réagissent différements...

    Je me suis donc dis que cela pourrait être sympa de passer par une metaclasse pour nous retourner un descriptor, histoire que ce soit légèrement moins long à écrire tout en procurant le petit avantage sus-cité... j'ai donc repris exactement la mécanique de Thierry en remplaçant seulement la property par un descriptor...

    quelquechose du genre :
    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
    32
    class DescriptorTemplate(object):
        def __get__(*args):pass
        def __set__(*args):pass
        def __init__(self,val,getf,setf):
            self._val=val
            DescriptorTemplate.__get__=getf
            DescriptorTemplate.__set__=setf
     
    class Meta(type):
        def __new__(cls,name,base,attr):
            if name=='Descriptor':
                return type.__new__(cls,name,base,attr)
            else:
                return DescriptorTemplate(attr.get('val'),attr.get('get'),attr.get('set'))
     
    class Descriptor:
        __metaclass__=Meta
     
    class Test(object):
        class x(Descriptor):
            val=5
            def get(self,obj,objtype):return self._val
            def set(self,obj,val):self._val=val%5
        class y(Descriptor):
            val=128
            def get(self,obj,objtype):return self._val
            def set(self,obj,val):self._val=val%63
     
    print Test.x,Test.y #resultat : 5 128
    Test().y=128
    Test().x=6
    print Test.x,Test.y #resultat : 6 2
    EDIT: Arf, en fait, y'a un cou.. dans le'pâté comme qui dirait, puisque après la création du descriptor y, le x à les mêmes méthode get et set que celles de y... Que doit-on modifier pour obtenir qu'à chaque nouvelle déclaration de classe enfant de Descriptor, les méthodes get et set leur étant associées ne soient donc associées qu'a ces dernières ? Cause remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def __init__(self,val,getf,setf):
            self._val=val
            DescriptorTemplate.__get__=getf
            DescriptorTemplate.__set__=setf
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def __init__(self,val,getf,setf):
            self._val=val
            self.__get__=getf
            self.__set__=setf
    ne marche pas vraiment (du tout en fait )...

  8. #8
    Membre éclairé
    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
    Points : 773
    Points
    773
    Par défaut
    La nuit porte conseil, j'ai finalement réussi ce que je voulais, et c'est même un peu plus concis que le précédent code (juste un peu) :
    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
    class Meta(type):
        def __new__(cls,name,base,attr):
            if name=='Descriptor':
                return type.__new__(cls,name,base,attr)
            else:
                return type.__new__(cls,name,tuple(),dict(__module__=Meta.__module__,_val=attr.get('val'),__get__=attr.get('get'),__set__=attr.get('set')))()
     
    class Descriptor:
        __metaclass__=Meta
     
    class Test(object):
        class x(Descriptor):
            val=4
            def get(self,obj,objtype):return self._val
            def set(self,obj,val):self._val=val%5
        class y(Descriptor):
            val=60
            def get(self,obj,objtype):return self._val
            def set(self,obj,val):self._val=val%63
     
    print Test.x,Test.y
    Test().y=128
    Test().x=6
    print Test.x,Test.y
    print globals()
    Ce que le script affiche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4 60
    1 2
    {'Meta': <class '__main__.Meta'>, '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'D:\\common-data\\Python\\lib\\Descriptor.py', 'Descriptor': <class '__main__.Descriptor'>, 'pyscripter': <module 'pyscripter' (built-in)>, 'Test': <class '__main__.Test'>, '__name__': '__main__', '__doc__': None}

  9. #9
    Membre émérite
    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 : 60
    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
    Points : 2 533
    Points
    2 533
    Par défaut
    Je ne comprend pas vraiment ou tu veux en venir.

    Tu as d'une part des propriétés de classes et des propriétés d'instance qui sont deux choses complètement différentes et qu'il est préférable, d'après moi, de ne pas nommer de la même manière.

    D'autre part le but d'un descripteur est de définir une logique d'accès à la propriété et la tu codes la logique dans la classe sur le set : self._val=val%5 et self._val=val%63.

    Enfin j'ai du mal à cerner ce que tu cherches à obtenir précisément !!
    Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !

    On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.

  10. #10
    Membre éclairé
    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
    Points : 773
    Points
    773
    Par défaut
    Ta remarque m'a poussé à me dire que je n'avais pas tout compris... donc après d'autres test, je viens seulement de comprendre que les properties ne concernait concretement que les instances... contrairement aux descriptor qu'on ne peut toutefois "seter" qu'à partir d'une instance...

    Quoi qu'il en soit, si l'on veut une dizaine de descriptors avec des comportements différents, ça reste vraiment fastidieux à écrire... et c'est pas forcément ce qu'il ya de plus aisé pour s'y retrouver dans le code source...

    Donc quand j'ai vu le code de Thierry, j'ai trouvé ça assez élégant, et je me suis dit qu'adapter cette façon de faire aux descriptors pourrais ammener plus de clarté dans le code source ainsi qu'une façon un peu moins longue de les écrire... voilà où je voulais en venir, ni plus ni moins...

    PS: les contenus des méthodes set n'avaient d'autre but que de produire un résultat bien précis prouvant que ces méthodes fonctionnaient bien... Et tant que ça marche comme on le souhaite...

  11. #11
    Membre émérite
    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 : 60
    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
    Points : 2 533
    Points
    2 533
    Par défaut
    Désolé, mais je comprend toujours pas la démarche !! Doit me faire vieux, j'ai le cerveau lent :p

    En reprenant mon exemple du départ. tu as d'une part la définition du descripteur :

    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 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
    Alors oui c'est vrai ça peut paraître un peu long, mais le but n'est pas de créer un descripteur par propriétés non plus, sinon autant le coder en setter/getter.


    Et après on a la déclaration de la propriété :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class MyClass(object):
        x = MyIntProperty(10)
        y = MyIntProperty()
    C'est la que l'on ai censé avoir beaucoup de propriétés utilisant les prescripteurs. Et là, on peut pas vraiment faire plus concis :p

    En restant sur ce schéma, je ne comprend toujours pas ou tu veux en venir.

    Que veux tu gagner vraiment ?
    - Moins de lignes de codes ?
    - Meilleure lisibilité ?
    Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !

    On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.

  12. #12
    Membre éclairé
    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
    Points : 773
    Points
    773
    Par défaut
    En restant sur ton exemple de départ, MyCass.x et MyClass.y sont des propriété ayant la même logique d'accès/écriture, elle pointent toutes les deux sur les même méthodes __get__ et __set__. Si l'on avait voulu que la propriété MyClass.y ait une logique d'accès/écriture différente de MyClass.x, il aurait fallu écrire un autre descripteur avec sa propre logique d'accès... Imaginons maintenant qu'il faille que la class MyClass possède plus d'une dizaine de propriétés définies via des descriptors, avec pour chacune de ces propriétés (Descriptor en fait) une logique d'accès propre (unique donc), ça ferait un sacré pavé de Descriptors à écrire, et il faudrait s'y retrouver dans le code source... c'est dans ces conditions que de passer par une métaclasse peut se révéler fort avantageux, surtout en terme de lisibilité (dans le sens où y'a pas à cavaler à travers le code source pour trouver la logique d'accè/écriture), enfin je trouve... juges plutôt :

    Avec ecriture "mannuelle" des descriptor:
    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
    class DescV(object):
        def __init__(self,x=0):self.x=x
        def __get__(self,*args):return self.x
        def __set__(self,obj,val):
            if type(val)==int:self.x=val
    class DescW(object):
        def __get__(self,*args):return '$'*Test.v
        def __set__(self,obj,val):pass
    class DescX(object):
        def __init__(self,x=0):self.x=x
        def __get__(self,*args):return self.x
        def __set__(self,obj,val):self.x=val%5
    class DescY(object):
        def __init__(self,x=0):self.x=x
        def __get__(self,*args):return self.x
        def __set__(self,obj,val):self.x=val%63
     
    class Test(object):
        v=DescV(56)
        w=DescW()
        x=DescX(4)
        y=DescY(60)
     
    print Test.x,Test.y
    Test().y=128
    Test().x=6
    print Test.x,Test.y,Test.w
    print globals()
    Et maintenant avec la métaclasse (qu'on pourrait simplement mettre en module d'ailleurs):
    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
    32
    33
    34
    35
    36
    37
    class Meta(type):
        def __new__(cls,name,base,attr):
            if name=='Descriptor':
                return type.__new__(cls,name,base,attr)
            else:
                def dummy(*args):pass
                return type.__new__(cls,name,tuple(),dict(\
                                                        __module__=attr.get('__module__'),\
                                                        val=(attr.get('val') if 'val' in attr else None),\
                                                        __get__=(attr.get('get') if 'get' in attr else dummy)\
                                                        ,__set__=(attr.get('set') if 'set' in attr else dummy)))()
     
    class Descriptor:
        __metaclass__=Meta
     
    class Test(object):
        class v(Descriptor):
            val=56
            def get(self,*args):return self.val
            def set(self,obj,val):
                if type(val)==int: self.val=val
        class w(Descriptor):
            def get(self,*args): return '$'*Test.v
        class x(Descriptor):
            val=4
            def get(self,obj,objtype):return self.val
            def set(self,obj,val):self.val=val%5
        class y(Descriptor):
            val=60
            def get(self,obj,objtype):return self.val
            def set(self,obj,val):self.val=val%63
     
    print Test.x,Test.y
    Test().y=128
    Test().x=6
    print Test.x,Test.y,Test.w
    print globals()
    C'est au finale une une économie de touches tapées par définition de Descriptor d'environ 34 touches, l'économie en terme de longueur n'est réelle que si le nombre de Descriptors ayant un logique d'accès/écriture unique est conséquent. Mais, encore c'est, je trouve, surtout un gain de lisibilité pour connaitre la logique de chaques descriptor. Donc simplifions au maximum en disant que les intérêts de cette méthode sont avant-tout estétiques, et éventuellement économique pour les doigts et l'imagination (un seul nom à trouver et non celui de la variable et du descriptor)... feignant jusqu'au bout des doigt

  13. #13
    Membre émérite
    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 : 60
    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
    Points : 2 533
    Points
    2 533
    Par défaut
    Pourquoi pas, mais pour moi, le but d'un descripteur est de mutualiser un comportement.

    Pour résoudre le problème que tu poses, j'aurais tendance à juste utiliser des property, même si c'est un peu plus verbeux. Ça reste plus lisible et sûrement moins lourd que de créer une classe pour chaque propriété.

    Mais chacun sa façon de voir
    Si ce message vous a semblé utile, il est possible qu'il soit utile à d'autres personnes. Pensez au . Et n'oubliez pas le le moment venu !

    On n'a pas à choisir si l'on est pour ou contre la décroissance, elle est inéluctable, elle arrivera qu'on le veuille ou non.

Discussions similaires

  1. QGIS : lenteur pour afficher les listes des vues dans &quot;Ajouter une table PostGIS&quot;
    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