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 :

Manipulation d'enum et de classes : Questions très basiques pour la modélisation d'une coupe de Tennis.


Sujet :

Python

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 51
    Points : 44
    Points
    44
    Par défaut Manipulation d'enum et de classes : Questions très basiques pour la modélisation d'une coupe de Tennis.
    Bonjour!

    Je débute avec la POO en python et je dois modéliser un tournoi de Tennis que je devrais représenter et manipuler dans un site réalisé avec django, j'aurais besoin d'un peu d'aide pour mes premières classes.

    J'ai déjà du mal avec le début de mon code :
    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
    from enum import Enum
     
    class Game(Enum):
        NONE = -1
        ZERO = 0
        ONE = 1
        TWO = 2
        THREE = 3
        FOUR = 4
        FIVE = 5
        SIX = 6
        SEVEN = 7
     
        def __init__(self, value = Game.NONE):
            self = value
     
    class Set():
        A = Game(Game.NONE)
        B = Game(Game.NONE)
    Ces deux premières classes sont censées représenter le nombre de jeux (Game) dans un set (Set).
    Comme le nombre de valeurs pouvant représenter le nombre de jeux dans un set, j'ai voulu limiter les possibilités aux quelques valeurs que j'ai tenté de définir dans la classe Game.
    J'ai pour cela utilisé Enum : Était-ce judicieux? L'instance (<-pas tout à fait sûr du terme) d'un enum est-elle une valeur prise dans un ensemble pré-défini ou justement cet ensemble de valeurs?

    Dans la classe Set j'ai voulu définir les différents champs comme étant véritablement des instances d'objets et non des références vers ces objets (comme le permet la classe ForeignKey avec Django), ai-je utilisé la bonne méthode pour cela?

    Par contre quand j'utilise ce code en l'état, j'ai une erreur "Game name is not defined"

    Ne me tenez pas rigueur de mes maladresses! Je suis là pour apprendre et progresser.

    Je vous remercie par avance pour votre aide.

  2. #2
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 51
    Points : 44
    Points
    44
    Par défaut
    Ok, pour résoudre l'erreur que j'avais, j'ai juste modifié le code de cette manière :
    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
    from enum import Enum
     
    class Game(Enum):
        NONE = -1
        ZERO = 0
        ONE = 1
        TWO = 2
        THREE = 3
        FOUR = 4
        FIVE = 5
        SIX = 6
        SEVEN = 7
     
        def __init__(self, value = NONE): # ici, j'ai remplacé Game.NONE par NONE
            self = value
     
    class Set():
        A = Game(Game.NONE)
        B = Game(Game.NONE)
    Cependant j'aimerais savoir si cette manière de faire est correcte J'ai un peu de mal à manipuler mes classes via la console pour l'instant :S

  3. #3
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par vmonteco Voir le message
    Ok, pour résoudre l'erreur que j'avais, j'ai juste modifié le code de cette manière :
    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
    from enum import Enum
     
    class Game(Enum):
        NONE = -1
        ZERO = 0
        ONE = 1
        TWO = 2
        THREE = 3
        FOUR = 4
        FIVE = 5
        SIX = 6
        SEVEN = 7
     
        def __init__(self, value = NONE): # ici, j'ai remplacé Game.NONE par NONE
            self = value
     
    class Set():
        A = Game(Game.NONE)
        B = Game(Game.NONE)
    Cependant j'aimerais savoir si cette manière de faire est correcte J'ai un peu de mal à manipuler mes classes via la console pour l'instant :S
    Bonjour,

    Il me semble qu'un bon cours vaut mieux que mille explications : http://www.developpez.net/forums/d13...r/#post7516008

    @+.

  4. #4
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 51
    Points : 44
    Points
    44
    Par défaut
    Bonjour tarball, merci pour ta réponse.

    J'étudie effectivement les bases du python pour la POO, j'en ai besoin il m'en manque, donc ce cours est le bienvenu même si j'étudie avec un bouquin à côté, merci beaucoup!
    Mais histoire de régler ce soucis qui me bloque un peu, pourrais-tu plutôt m'indiquer que chercher dans mon livre même sans forcément me l'expliquer? Le Python me semble bien riche par rapport au C et j'ai peur que cela me prenne du temps de trouver ce qui correspondrait à ce que je cherche.
    J'ai plus ou moins compris que mes difficultés à manipuler mes classes dans le shell étaient dues au fait que je me méprenais sur le type de ce que j'obtenais avec ce que j'ai présenté plus haut.

    J'ai cru obtenir une valeur parmis un ensemble restreint avec ce que j'ai fait, mais en fait il me semblerait plutôt que j'obtiens justement cet ensemble restreint sous forme d'un set, je prenais donc l'enum que j'ai utilisé comme l'équivalent de l'enum du C, mais à tort?
    Lorsque je fais a = Game(), puis a = 2, je n'assigne pas une valeur à a parmi les valeurs disponibles de ce set, mais je change carrément le type de a pour en faire un entier. Du coup lorsque je lui assigne une valeur sortant de ce set c'est normal que le shell ne me sorte pas d'erreur, ce que je ne comprenais pas au début. Est-ce que c'est plus ou moins ça?

    Du coup, si je souhaite que mon objet se comporte comme un enum, mais que la simple assignation est susceptible d'en changer carrément le type (du coup mon enum n'en serait plus un), l'équivalent de l'enum du C en Python peut-il vraiment exister dans la lib standard?..

    Faudrait-il donc que je crée une méthode dans ma classe pour faire l'assignation de valeur, et que j'ajoute un champ pour contenir cette valeur? Et faudrait-il également que je fasse en sorte que la méthode d'assignation me retourne une erreur si la valeur que je lui passe?

    Quelque-chose de ce genre me semblerait envisageable alors :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Ma_classe():
        values = (1, 2, 3, 4)
     
        def assign(self, val):
            if (val in values):
                self.value = val
            else:
                raise error        #Je verrai plus tard pour cette ligne, si ça n'est pas exact et que je dois corriger :)
     
        def __init__(self, val=1):
            assign(self, val)
    Si on ne tient pas compte des quelques erreurs qui se sont sans doute glissées dans ce code, ela est-il viable sur le principe?

    À moins qu'il n'existe quelque-chose en Python fait pour cela à la base?

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Citation Envoyé par vmonteco Voir le message
    Bonjour tarball, merci pour ta réponse.

    J'étudie effectivement les bases du python pour la POO, j'en ai besoin il m'en manque, donc ce cours est le bienvenu même si j'étudie avec un bouquin à côté, merci beaucoup!
    Mais histoire de régler ce soucis qui me bloque un peu, pourrais-tu plutôt m'indiquer que chercher dans mon livre même sans forcément me l'expliquer? Le Python me semble bien riche par rapport au C et j'ai peur que cela me prenne du temps de trouver ce qui correspondrait à ce que je cherche.
    C est un langage très puissant, mais il ne faut pas se calquer sur le raisonnement C pour écrire en Python.

    Python a sa propre philosophie de codage (par exemple, les enums ne sont pas très usités en Python, d'où leur relégation aux fins fonds d'un module), philosophie de codage qui est très souple et qui permet une très grande abstraction dans les types de données.

    J'ai plus ou moins compris que mes difficultés à manipuler mes classes dans le shell étaient dues au fait que je me méprenais sur le type de ce que j'obtenais avec ce que j'ai présenté plus haut.
    Il y a surtout un problème d'ordre pratique : coder des classes dans une console interactive, c'est très vite la croix - la bannière.

    Préférez utiliser l'éditeur IDLE fourni d'office avec Python et rédiger vos essais dans un fichier de script - e.g. test.py - qu'il vous suffira ensuite de tester en pressant la touche F5 de votre clavier ("Run script" dans IDLE).

    En plus, IDLE dispose d'une console interactive Python qui vous offrira un certain niveau de suivi et de débogage de vos scripts.

    J'ai cru obtenir une valeur parmis un ensemble restreint avec ce que j'ai fait, mais en fait il me semblerait plutôt que j'obtiens justement cet ensemble restreint sous forme d'un set, je prenais donc l'enum que j'ai utilisé comme l'équivalent de l'enum du C, mais à tort?
    Oui, oubliez les enums C en Python : on n'en a que très rarement besoin. On raisonne tout à fait différemment en Python, avec d'autres structures de données et - surtout - d'autres façons de faire.

    Lorsque je fais a = Game(), puis a = 2, je n'assigne pas une valeur à a parmi les valeurs disponibles de ce set, mais je change carrément le type de a pour en faire un entier. Du coup lorsque je lui assigne une valeur sortant de ce set c'est normal que le shell ne me sorte pas d'erreur, ce que je ne comprenais pas au début. Est-ce que c'est plus ou moins ça?
    Si vous faites a = Game() puis ensuite a = 2, vous dites à Python que vous voulez d'abord un objet Game() (qui est une instance de la classe Game, une copie personnalisable de Game) et qu'ensuite vous voulez réinitialiser votre variable a à la valeur entière 2. Résultat des courses : en remplaçant l'objet Game() par l'entier 2 dans a, vous avez tout bonnement supprimé l'objet Game() et rien de plus. Donc a aura la dernière valeur en date 2 et votre objet Game() n'existera plus - et ne sera plus exploitable, évidemment.

    Du coup, si je souhaite que mon objet se comporte comme un enum, mais que la simple assignation est susceptible d'en changer carrément le type (du coup mon enum n'en serait plus un), l'équivalent de l'enum du C en Python peut-il vraiment exister dans la lib standard?..
    La vraie question serait plutôt : avez-vous vraiment besoin d'un enum sous Python ? Que cherchez-vous à faire exactement ? Clarifiez vos idées, documentez-vous sur les dictionnaires, les listes, les tuples, et vous verrez que ce n'est pas forcément utile de recourir à des enums.

    Faudrait-il donc que je crée une méthode dans ma classe pour faire l'assignation de valeur, et que j'ajoute un champ pour contenir cette valeur? Et faudrait-il également que je fasse en sorte que la méthode d'assignation me retourne une erreur si la valeur que je lui passe?

    Quelque-chose de ce genre me semblerait envisageable alors :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Ma_classe():
        values = (1, 2, 3, 4)
     
        def assign(self, val):
            if (val in values):
                self.value = val
            else:
                raise error        #Je verrai plus tard pour cette ligne, si ça n'est pas exact et que je dois corriger :)
     
        def __init__(self, val=1):
            assign(self, val)
    Cela est-il viable?

    À moins qu'il n'existe quelque-chose en Python fait pour cela à la base?
    On n'utilise quasiment plus des valeurs numériques de constantes comme en C e.g.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define ERR_FILE_NOT_FOUND 0xFABC0004
    ou encore
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    enum niveau_joueur { DEBUTANT = 0, MOYEN = 10, EXPERT = 20, CHAMPION = 100 };
    car Python permet de gérer les données nominativement en associant à des clés de dictionnaire des valeurs e.g.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    niveau_joueur = {"debutant": 0, "moyen": 10, "expert": 20, "champion": 100}
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    niveau_joueur = {0: "debutant", 10: "moyen", 20: "expert", 100: "champion"}
    si vous préférez accéder vos données par niveau numérique.

    Pour faire court, vous n'avez pas besoin de créer une classe ou une enum pour faire ce genre de choses, une simple variable avec un objet dictionnaire dict() (notation dico = {clé: valeur, clé: valeur, ...etc...} suffit amplement.

    Pour vous donner un exemple de code, supposez que vous ayez une classe (structure) Application dans laquelle vous avez besoin d'une énumération NIVEAU_JOUEUR (on note généralement les structures appelées à être CONSTANTES en toutes majuscules - voir PEP 8 à ce sujet : http://legacy.python.org/dev/peps/pe...ng-conventions

    Vous écririez le début de votre classe comme ceci :

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
     
    class Application:
        """
            Mon application fait ceci cela
        """
     
        # ici, on déclare un dictionnaire de valeurs
        # accessibles par valeurs numériques
     
        NIVEAU_JOUEUR = {
              0: "débutant",
             10: "moyen",
             20: "expert",
            100: "champion",
        }
     
        # constructeur de la classe
        # pour obtenir une instance (copie) personnalisée
        # de la classe dans un objet
     
        def __init__ (self, niv_joueur):
            """
                on choisit les paramètres que l'on veut voir figurer
                lors de l'initialisation de la classe; ici, on attend
                @niv_joueur lors de la création d'un objet Application();
            """
     
            # membre de la classe
            # le pointeur self désigne
            # l'instance de la classe
            # en cours d'utilisation
     
            self.niveau_joueur = niv_joueur
     
        # end def
     
        def str_niveau_joueur (self):
            """
                si on veut le texte à la place de la valeur numérique,
                on appelle cette méthode;
            """
     
            return self.NIVEAU_JOUEUR[self.niveau_joueur]
     
        # end def
     
        @property
        def niveau_joueur (self):
            """
                cette notation spéciale permet de gérer spécifiquement
                un membre de la classe comme une propriété de classe;
                n'a de réel intérêt que si vous avez un traitement
                particulier à y faire;
            """
     
            return self.__niveau_joueur
     
        # end def
     
        @niveau_joueur.setter
        def niveau_joueur (self, value):
            """
                c'est ici qu'on contrôle si la valeur @value affectée à
                self.niveau_joueur existe dans le dictionnaire
                NIVEAU_JOUEUR que nous avons déclaré en tête de classe;
                accessoirement, on peut aussi gérer les erreurs, mais ce
                n'est pas obligatoire, étant donné que Python lèvera une
                exception si quelque chose ne va pas;
            """
     
            # on décide de gérer les erreurs
     
            if value not in self.NIVEAU_JOUEUR:
     
                raise ValueError("la valeur demandée n'est pas prise en charge.")
     
            else:
     
                self.__niveau_joueur = value
     
            # end if
     
        # end def
     
        @niveau_joueur.deleter
        def niveau_joueur (self):
            """
                on gère aussi la destruction d'une propriété si l'on a
                déclaré des membres privés comme self.__niveau_joueur,
                par exemple;
            """
     
            del self.__niveau_joueur
     
        # end def
     
    # end class Application
    Et vous utiliseriez votre classe comme ceci :

    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
    # test
     
    # avec un niveau joueur CORRECT
     
    mon_appli = Application(10)
     
    # on choisit d'afficher
    # ET la valeur numérique
    # ET le texte correspondant
    print(
        "Niveau joueur : {niv} - {txt}"
        .format(
            niv=mon_appli.niveau_joueur,
            txt=mon_appli.str_niveau_joueur(),
        )
    )
     
    # en précisant le paramètre nommément
     
    mon_appli = Application(niv_joueur=10)
     
    # on choisit d'afficher
    # ET la valeur numérique
    # ET le texte correspondant
    print(
        "Niveau joueur : {niv} - {txt}"
        .format(
            niv=mon_appli.niveau_joueur,
            txt=mon_appli.str_niveau_joueur(),
        )
    )
     
    # avec un niveau joueur INCORRECT
     
    mon_appli = Application(50)
     
    # on se prend l'erreur qu'on a gérée
     
    # i.e. ValueError: bla bla bla...
    Note : vous pouvez tout mettre ensemble dans un seul script, évidemment :

    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
     
    class Application:
        """
            Mon application fait ceci cela
        """
     
        # ici, on déclare un dictionnaire de valeurs
        # accessibles par valeurs numériques
     
        NIVEAU_JOUEUR = {
              0: "débutant",
             10: "moyen",
             20: "expert",
            100: "champion",
        }
     
        # constructeur de la classe
        # pour obtenir une instance (copie) personnalisée
        # de la classe dans un objet
     
        def __init__ (self, niv_joueur):
            """
                on choisit les paramètres que l'on veut voir figurer
                lors de l'initialisation de la classe; ici, on attend
                @niv_joueur lors de la création d'un objet Application();
            """
     
            # membre de la classe
            # le pointeur self désigne
            # l'instance de la classe
            # en cours d'utilisation
     
            self.niveau_joueur = niv_joueur
     
        # end def
     
        def str_niveau_joueur (self):
            """
                si on veut le texte à la place de la valeur numérique,
                on appelle cette méthode;
            """
     
            return self.NIVEAU_JOUEUR[self.niveau_joueur]
     
        # end def
     
        @property
        def niveau_joueur (self):
            """
                cette notation spéciale permet de gérer spécifiquement
                un membre de la classe comme une propriété de classe;
                n'a de réel intérêt que si vous avez un traitement
                particulier à y faire;
            """
     
            return self.__niveau_joueur
     
        # end def
     
        @niveau_joueur.setter
        def niveau_joueur (self, value):
            """
                c'est ici qu'on contrôle si la valeur @value affectée à
                self.niveau_joueur existe dans le dictionnaire
                NIVEAU_JOUEUR que nous avons déclaré en tête de classe;
                accessoirement, on peut aussi gérer les erreurs, mais ce
                n'est pas obligatoire, étant donné que Python lèvera une
                exception si quelque chose ne va pas;
            """
     
            # on décide de gérer les erreurs
     
            if value not in self.NIVEAU_JOUEUR:
     
                raise ValueError("la valeur demandée n'est pas prise en charge.")
     
            else:
     
                self.__niveau_joueur = value
     
            # end if
     
        # end def
     
        @niveau_joueur.deleter
        def niveau_joueur (self):
            """
                on gère aussi la destruction d'une propriété si l'on a
                déclaré des membres privés comme self.__niveau_joueur,
                par exemple;
            """
     
            del self.__niveau_joueur
     
        # end def
     
    # end class Application
     
     
    # test
     
    # avec un niveau joueur CORRECT
     
    mon_appli = Application(10)
     
    # on choisit d'afficher
    # ET la valeur numérique
    # ET le texte correspondant
    print(
        "Niveau joueur : {niv} - {txt}"
        .format(
            niv=mon_appli.niveau_joueur,
            txt=mon_appli.str_niveau_joueur(),
        )
    )
     
    # en précisant le paramètre nommément
     
    mon_appli = Application(niv_joueur=10)
     
    # on choisit d'afficher
    # ET la valeur numérique
    # ET le texte correspondant
    print(
        "Niveau joueur : {niv} - {txt}"
        .format(
            niv=mon_appli.niveau_joueur,
            txt=mon_appli.str_niveau_joueur(),
        )
    )
     
    # avec un niveau joueur INCORRECT
     
    mon_appli = Application(50)
     
    # on se prend l'erreur qu'on a gérée
     
    # i.e. ValueError: bla bla bla...
    Cliquez sur le lien "Sélectionner tout", copiez/collez ce code dans un fichier test.py sous IDLE, enregistrez puis pressez la touche F5 (run script) pour voir ce que cela donne.

    @+.

  6. #6
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 51
    Points : 44
    Points
    44
    Par défaut
    Merci pour cette réponse particulièrement complète!

    J'ai plus ou moins compris que mes difficultés à manipuler mes classes dans le shell étaient dues au fait que je me méprenais sur le type de ce que j'obtenais avec ce que j'ai présenté plus haut.
    Il y a surtout un problème d'ordre pratique : coder des classes dans une console interactive, c'est très vite la croix - la bannière.
    Préférez utiliser l'éditeur IDLE fourni d'office avec Python et rédiger vos essais dans un fichier de script - e.g. test.py - qu'il vous suffira ensuite de tester en pressant la touche F5 de votre clavier ("Run script" dans IDLE).
    J'ai dû mal m'exprimer, j'écris mes classes dans un *.py que je teste ensuite avec le shell python pour mieux comprendre ce que je fais le temps de maîtriser ce que j'aborde. Comme éditeur j'utilise Emacs et je lance mes scripts avec zsh. ^^

    Lorsque je fais a = Game(), puis a = 2, je n'assigne pas une valeur à a parmi les valeurs disponibles de ce set, mais je change carrément le type de a pour en faire un entier. Du coup lorsque je lui assigne une valeur sortant de ce set c'est normal que le shell ne me sorte pas d'erreur, ce que je ne comprenais pas au début. Est-ce que c'est plus ou moins ça?
    Si vous faites a = Game() puis ensuite a = 2, vous dites à Python que vous voulez d'abord un objet Game() (qui est une instance de la classe Game, une copie personnalisable de Game) et qu'ensuite vous voulez réinitialiser votre variable a à la valeur entière 2. Résultat des courses : en remplaçant l'objet Game() par l'entier 2 dans a, vous avez tout bonnement supprimé l'objet Game() et rien de plus. Donc a aura la dernière valeur en date 2 et votre objet Game() n'existera plus - et ne sera plus exploitable, évidemment.
    Entendu

    La vraie question serait plutôt : avez-vous vraiment besoin d'un enum sous Python ? Que cherchez-vous à faire exactement ? Clarifiez vos idées, documentez-vous sur les dictionnaires, les listes, les tuples, et vous verrez que ce n'est pas forcément utile de recourir à des enums.
    C'est une bonne question, étant donné que les scores dans un jeu au tennis sont limités à 4 valeurs numériques et une valeur "spéciale" (avantage), sortant du C je me suis en effet mis naturellement à la recherche d'un équivalent de l'enum du C.
    Un dictionnaire devrait faire l'affaire, même si un tuple serait peut-être plus cohérent pour son "caractère immuable", seulement je ne connais pas le moyen d'utiliser des couples clé-valeur dans un tuple à moins peut-être d'y insérer des mini-dicos un à un. Mais ça me semblerait moche.

    Si je réessaie selon vos conseils, cela pourrait-il donner ceci?
    J'ai préféré faire sans les decorators car j'en suis encore à les étudier, je ne connais pas encore assez la théorie pour passer à la pratique.
    J'ai tout de même essayé en reprenant votre code mais sans grand succès. Pour obtenir quelque-chose de fonctionnel j'ai du les commenter.
    Mais au moins cela semble fonctionner

    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
    # Class Game_Score
     
    class Game():
        VALUES = {
            0:'0',
            1:'15',
            2:'30',
            3:'40',
            4:'A',
            }
        # value = 0
     
        def __init__(self, val=0):
            """ val may be passed as a value in the dictionnary or as its key in
            the dictionnary. """
            self.assign(val)
     
        def __unicode__(self):
            return (u"%s" % (self.VALUES[self.value],))
     
        def __str__(self):
            return ("%s" % (self.VALUES[self.value],))
     
        # @property
        # def value(self):
        #     """ This attribute has to be a key contained by the dictionnary """
        #     print ('test')
        #     return (self._value)
     
    #    @value.setter
        def assign(self, val):
            """ This method assign val to the value if val is present as a key
            in VALUES or as its key if val is present as a value """
            if (self.VALUES.has_key(val)):
                self.value = val
            elif (val in self.VALUES.values()):
                for key in self.VALUES.keys():
                    if (self.VALUES[key] == val):
                        self.value = key
            else:
                raise (Exception(u"Value %s not permitted" % (val,)))
    Encore merci pour vos explication très claires et détaillées.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par vmonteco Voir le message
    Merci pour cette réponse particulièrement complète!
    J'ai préféré faire sans les decorators car j'en suis encore à les étudier, je ne connais pas encore assez la théorie pour passer à la pratique.
    J'ai tout de même essayé en reprenant votre code mais sans grand succès. Pour obtenir quelque-chose de fonctionnel j'ai du les commenter.
    Mais au moins cela semble fonctionner

    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
    # Class Game_Score
     
    class Game():
        VALUES = {
            0:'0',
            1:'15',
            2:'30',
            3:'40',
            4:'A',
            }
        # value = 0
     
        def __init__(self, val=0):
            """ val may be passed as a value in the dictionnary or as its key in
            the dictionnary. """
            self.assign(val)
     
        def __unicode__(self):
            return (u"%s" % (self.VALUES[self.value],))
     
        def __str__(self):
            return ("%s" % (self.VALUES[self.value],))
     
        # @property
        # def value(self):
        #     """ This attribute has to be a key contained by the dictionnary """
        #     print ('test')
        #     return (self._value)
     
    #    @value.setter
        def assign(self, val):
            """ This method assign val to the value if val is present as a key
            in VALUES or as its key if val is present as a value """
            if (self.VALUES.has_key(val)):
                self.value = val
            elif (val in self.VALUES.values()):
                for key in self.VALUES.keys():
                    if (self.VALUES[key] == val):
                        self.value = key
            else:
                raise (Exception(u"Value %s not permitted" % (val,)))
    Encore merci pour vos explication très claires et détaillées.
    Petit corrigé vite fait :

    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
    44
    45
    46
    47
    48
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
     
    from __future__ import unicode_literals
     
    # Class GameScore
     
    class GameScore:
     
        # faites simple !
     
        SCORES = ('0', '15', '30', '40', 'A')
     
        def __init__(self, value=0):
            """ @value may either be score index or direct string value """
            self.assign(value)
        # end def
     
        def __str__(self):
            return str(self.SCORES[self.index])
        # end def
     
        def assign(self, value):
            """ sets up score @value as index """
            if value in self.SCORES:
                self.index = self.SCORES.index(value)
            elif 0 <= value < len(self.SCORES):
                self.index = value
            else:
                raise ValueError("value '{}' is not permitted".format(value))
            # end if
        # end def
     
    # end class GameScore
     
    # test
     
    score = GameScore(2)
     
    print score.index, score
     
    score = GameScore('A')
     
    print score.index, score
     
    score = GameScore('toto') # ValueError !
     
    score = GameScore(-1) # ValueError !
    @+.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 01/07/2015, 10h55
  2. [OS X] [Bash 3] Question de débutant pour l'évaluation d'une expression booléenne
    Par flamant dans le forum Shell et commandes POSIX
    Réponses: 5
    Dernier message: 08/11/2013, 10h52
  3. [Tableaux] question très simple
    Par H-bil dans le forum Langage
    Réponses: 14
    Dernier message: 28/05/2006, 13h29
  4. Question très bête : récupérer la valeur de retour d'une fct
    Par pekka77 dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 28/10/2005, 17h57
  5. [Servlet + Class] question concernant plusieurs connections
    Par ShinJava dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 29/11/2004, 16h39

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