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 :

Classe-Définir un attribut via une chaîne


Sujet :

Python

  1. #21
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 776
    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 776
    Par défaut Just names
    Salut,

    Puisqu'on discute horreurs permises par la programmation dynamique.
    Il y a quelques temps je me suis intéressé à la simplification de patterns GOF que permettait Python. Un de ceux là est "State".

    En gros, pour représenter l'état d'un objet on lui associe une classe S1, S2, S3, .... qui sont sous-classe d'une classe abstraite A.
    L'état est donc mémorisé dans un attribut style self._state = S1(...).

    En fonction de... l'état de notre objet doit être changé pour refléter le nouvel état. Classiquement self._state = S2(...) ce qui crée une instance de S2 et libère S1.

    Une façon permise par Python et à n'utiliser que si on comprends ce qu'on fait pour 'changer' l'état est de faire: self._state.__class__ = S2

    On peut donc "s'amuser" à changer des choses bien plus "tordues" juste parce que le monde python est un __dict__ de __dict__

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

  2. #22
    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
    Salut wiztricks,

    je trouve que tu ne vas pas assez loin. Voici la description du pattern State, tel que présenté dans la version française du livre du GOF lui-même (l'emphase est de moi):
    Permet à un objet de modifier son comportement, quand son état interne change. Tout se passera comme si l'objet changeait de classe.
    En Python, l'objet peut réellement changer de classe, le pattern est donc trivialement:
    Passer par un attribut _state et une délégation, c'est juste faire des ronds de jambe au GOF

    Enfin, pour être plus précis, pour décrire le pattern il faudrait une classe mère (abstraite), qui contient la partie commune à tous les états (ce qui se trouve dans la classe "Context" du pattern, pour l'occasion fusionnée avec la classe abstraite "State"), et plusieurs classes dérivées pour chacun des états.

    [EDIT]
    Un exemple (un peu tiré par les cheveux, mais qui je l'espère illustre bien le pattern):
    Implémentation d'une file de taille fixe:
    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
    38
    39
    40
    41
    42
    43
    class EmptyQueueError(Exception): pass
    class FullQueueError(Exception): pass
     
    class Queue(object):
        def __init__(self, size):
            self._size = size
            self._data = []
            self.__class__ = EmptyQueue
     
        def add(self, value):
            self._data.append(value)
     
        def get(self):
            return self._data.pop(0)
     
    class EmptyQueue(Queue):
        def add(self, value):
            Queue.add(self, value)
            self.__class__ = PartialyFilledQueue
     
        def get(self):
            raise EmptyQueueError()
     
    class PartialyFilledQueue(Queue):
        def add(self, value):
            Queue.add(self, value)
            if len(self._data) == self._size:
                self.__class__ = FullQueue
     
        def get(self):
            value = Queue.get(self)
            if len(self._data) == 0:
                self.__class__ = EmptyQueue
            return value
     
    class FullQueue(Queue):
        def add(self, value):
            raise FullQueueError()
     
        def get(self):
            value = Queue.get(self)
            self.__class__ = PartialyFilledQueue
            return value

  3. #23
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 776
    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 776
    Par défaut
    Salut Dividee

    Permet à un objet de modifier son comportement, quand son état interne change.Tout se passera comme si l'objet changeait de classe.
    Pour ce qui est de changer la classe à la volée: la différence entre self._state.__class__ et self.__class__ n'est que relative.

    Si l'ensemble des méthodes (comportement) de l'objet dépendent de son état courant, on peut bien sûr réduire la représentation de la chose aux seules sous classes représentant "l'état". Dans ce cas, plus la peine de passer par un attribut _state....

    Mais c'est quand même lié à des cas particulier et donc quelque peu réducteur par rapport à la mise en œuvre du pattern "en général".
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #24
    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
    très intéressant cet exemple de pattern dividee.

    J'avoue avoir encore un peu de mal à bien gérer les changements d'états. Même si comme tu le dis l'exemple est tiré par les cheveux (on aurait facilement pu se passer de cette approche ici), la technique exposée est claire.

    On peut également facilement extrapoler cette technique avec l'approche légèrement différente proposée par wiztricks (en déléguant le changement d'état à un attribut de la classe).

    wiztricks, j'ai cru comprendre que tu essayais d'adapter certains pattern du GoF à Python. Je me rends assez régulièrement sur cette page:

    http://en.wikipedia.org/wiki/Design_...ter_science%29

    Certains des patterns ont des exemples Python. J'utilise très fréquemment certains d'entre eux. Je serais curieux de voir les adaptations que tu as faites à moins que ces travaux ne soient pas partageables

  5. #25
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 776
    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 776
    Par défaut
    Salut,

    Citation Envoyé par kango Voir le message
    Certains des patterns ont des exemples Python. J'utilise très fréquemment certains d'entre eux. Je serais curieux de voir les adaptations que tu as faites à moins que ces travaux ne soient pas partageables
    Hélas, cela n'ayant rien de très original - google truc donne des tas d'exemples - je n'ai pas pris la peine de mettre en forme les choses pour que ce soit "lisible".
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #26
    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
    ok, on ne sait jamais

    merci quand même

  7. #27
    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
    Citation Envoyé par wiztricks Voir le message
    Si l'ensemble des méthodes (comportement) de l'objet dépendent de son état courant, on peut bien sûr réduire la représentation de la chose aux seules sous classes représentant "l'état". Dans ce cas, plus la peine de passer par un attribut _state....

    Mais c'est quand même lié à des cas particulier et donc quelque peu réducteur par rapport à la mise en œuvre du pattern "en général".
    - W
    Je ne pense pas que ce soit réducteur par rapport au pattern. Le comportement qui ne dépend pas de l'état va dans la classe parente. Je pense au contraire que c'est tout à fait dans l'esprit du pattern, une simplification de son implémentation qui exploite le dynamisme de python.

  8. #28
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 776
    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 776
    Par défaut

    Citation Envoyé par dividee Voir le message
    Je ne pense pas que ce soit réducteur par rapport au pattern. Le comportement qui ne dépend pas de l'état va dans la classe parente. Je pense au contraire que c'est tout à fait dans l'esprit du pattern, une simplification de son implémentation qui exploite le dynamisme de python.
    Certes mais lorsqu'on écrit:
    Permet à un objet de modifier son comportement, quand son état interne change. Tout se passera comme si l'objet changeait de classe.
    Ca signifie que l'appelant reçoit un objet O dont le comportement change comme si l'objet changeait de classe.
    Et le "comme si" en bon français signifie qu'il n'en change pas.

    A défaut, on change l'interface...

    Et ce faisant on parle d'autre chose que du pattern State - ce n'est pas interdit - juste que les informaticiens souffrent trop d'un manque d'abstractions partagées pour qu'on puisse se permettre de gribouiller les rares que nous pourrions avoir.

    Ce qui ont le temps pourraient lire un article de A.Martelli & C° sur un sujet similaire
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #29
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    J’aimerais bien savoir ce que ça veut dire « changer de classe »

  10. #30
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 776
    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 776
    Par défaut
    Citation Envoyé par eyquem Voir le message
    J’aimerais bien savoir ce que ça veut dire « changer de classe »
    Imaginons que notre objet "o" soit de la classe Commande et que nos états soient EnCours, Livré, ...
    Si on applique ce que propose Dividee, la classe de "o" sera EnCours, Livrée,... une fonction de l'état et non plus "Commande".

    Ce n'est pas grave: on pourrait documenter les différentes valeurs retournées par type(o) dans ce cas, ou n'utiliser qu'isinstance (..., Commande) ou fournir un is_commande qui fait ce qu'il faut.

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

  11. #31
    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
    Citation Envoyé par wiztricks Voir le message
    Ca signifie que l'appelant reçoit un objet O dont le comportement change comme si l'objet changeait de classe.
    Et le "comme si" en bon français signifie qu'il n'en change pas.
    J'ai parlé de l'esprit du pattern, pas de la lettre. C'est évident qu'ils n'allaient pas écrire que l'objet changeait de classe, vu que ce n'est pas concevable dans le modèle orienté objet classique (statiquement typé) sur lequel le GOF se base. Mais ce pattern existe justement, à mon sens, pour contourner cette limitation. Limitation qui n'existe pas en python. Il n'y a donc rien à contourner.

    Et ce faisant on parle d'autre chose que du pattern State - ce n'est pas interdit - juste que les informaticiens souffrent trop d'un manque d'abstractions partagées pour qu'on puisse se permettre de gribouiller les rares que nous pourrions avoir.
    Le pattern se réduit à si peu de chose en Python qu'on pourrait lui disputer le statut de design pattern, mais il me semble que c'est un technique assez peu connue qui mérite donc quand-même qu'on lui donne un nom et un statut. Appliquer le State Pattern à la lettre en Python me semble lourd et malvenu.

    Mais je sais que les patterns ont aussi une vocation de communication (abstraction partagée) et je comprends donc ton souci de donner à cette technique le nom de State Pattern.

    Ce qui ont le temps pourraient lire un article de A.Martelli & C° sur un sujet similaire
    Merci pour le lien, je lirais l'article dès que j'ai le temps.

    Imaginons que notre objet "o" soit de la classe Commande et que nos états soient EnCours, Livré, ...
    Si on applique ce que propose Dividee, la classe de "o" sera EnCours, Livrée,... une fonction de l'état et non plus "Commande".
    Petit détail, j'aurais appelé les sous-classes "CommandeEnCours", "CommandeLivrée", ... pour qu'il soit bien apparent que ce bien toujours des Commandes. C'est bien la sémantique de l'héritage; une instance d'une sous-classe est aussi un instance de toutes ses super-classes. La classe effective change, mais ça reste une Commande.

    Ce n'est pas grave: on pourrait documenter les différentes valeurs retournées par type(o) dans ce cas, ou n'utiliser qu'isinstance (..., Commande) ou fournir un is_commande qui fait ce qu'il faut.
    Je ne suis pas sûr de bien suivre. L'utilisateur n'a que la classe Commande à connaître, les sous-classes ne font pas partie de l'interface. C'est vrai que les sous-classes vont "leaker" (être visibles côté client), mais en Python, on n'est pas à ça près (il n'y a de toute façon pas de concept d'interface dans le langage, tous les attributs sont publics, etc.).
    C'est effectivement isinstance qu'il faut utiliser s'il faut distinguer le type Commande d'autres types (c'est pas pour rien que type(o) == Commande c'est "beurk"), mais je ne vois pas ce qui aurait pu être grave mais ne l'est pas grâce à cela.

  12. #32
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 776
    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 776
    Par défaut
    Citation Envoyé par dividee Voir le message
    J'ai parlé de l'esprit du pattern, pas de la lettre. ....Il n'y a donc rien à contourner.
    Regardes le pattern "Template method", il propose une réalisation de changement de comportement "par héritage" similaire à la tienne.
    Le pattern "State" propose lui une réalisation "par délégation".

    Il n'y a pas - sur ce point - de "limitation" qui empêcheraient les langages "compilés" de réaliser ce type de liaison "par héritage" : les contextes, l'histoire qu'on raconte sont différentes ainsi que la réalisation proposée en illustration de solution.

    Le pattern se réduit à si peu de chose en Python qu'on pourrait lui disputer le statut de design pattern...
    J'étais tombé sur une présentation sur les patterns GOF en Python faite par Martelli ou Simonetto à l'occasion d'un PyCon... Je n'arrive pas à remettre la main dessus mais çà raconte à peu près la même chose: en Python, la réalisation de nombre de patterns peuvent se faire avec Template method.

    Mais nous retrouvons quand même l'interrogation qui nous a amené ici: est ce que le "techniquement possible" suffit à rendre acceptable certaines pratiques?

    Mais je sais que les patterns ont aussi une vocation de communication (abstraction partagée)
    Absolument! Et la réduction de nombre de patterns de conception au seul pattern Template method, nous fait perdre des capacités de nuances et de précision nécessaires à la conception de codes complexes et indispensables à la réalisation de codes maintenables.

    Hélas, la richesse de ces abstractions ne peut être appréciée de façon tangible que lorsqu'on doit communiquer avec une certaine précision et devoir s'amuser à contrôler que les rendus répondent aux attentes.

    Ce qui suppose des projets conséquents côté taille des équipes, durée,...
    Les Pythonistes étant plutôt "cow-boys" sont rarement confrontés à ce genre de phénomènes.

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

  13. #33
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Et moi qui pensais poser une question à la con...

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Définir l'encodage d'une chaîne
    Par Adorien dans le forum Langage
    Réponses: 2
    Dernier message: 12/04/2010, 12h22
  2. Lancer une procédure via une chaîne de caractère
    Par rstephane dans le forum VBA Outlook
    Réponses: 1
    Dernier message: 02/06/2009, 17h11
  3. [RegEx] Changer la valeur d’un attribut dans une chaîne
    Par sara21 dans le forum Langage
    Réponses: 2
    Dernier message: 20/07/2008, 19h31
  4. Réponses: 2
    Dernier message: 17/04/2007, 17h14
  5. Réponses: 4
    Dernier message: 28/03/2007, 22h23

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