Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Licence CC BY-NC-ND Thierry Parmentelat & Arnaud Legout Inria - UCA

Complément - niveau basique

On trouve dans d’autres langages la notion de types énumérés.

L’usage habituel, c’est typiquement un code d’erreur qui peut prendre certaines valeurs précises. Pensez par exemple aux codes prévus par le protocole HTTP. Le protocole prévoit un code de retour qui peut prendre un ensemble fini de valeurs, comme par exemple 200, 301, 302, 404, 500, mais pas 90 ni 110.

On veut pouvoir utiliser des noms parlants dans les programmes qui gèrent ce type de valeurs, c’est une application typique des types énumérés.

La bibliothèque standard offre depuis Python-3.4 un module qui s’appelle sans grande surprise enum, et qui expose entre autres une classe Enum. On l’utiliserait comme ceci, dans un cas d’usage plus simple :

from enum import Enum
class Flavour(Enum):
    CHOCOLATE = 1
    VANILLA = 2
    PEAR = 3
The history saving thread hit an unexpected error (OperationalError('attempt to write a readonly database')).History will not be written to the database.

vanilla = Flavour.VANILLA

Un premier avantage est que les représentations textuelles sont plus parlantes :

str(vanilla)
'Flavour.VANILLA'
repr(vanilla)
'<Flavour.VANILLA: 2>'

Vous pouvez aussi retrouver une valeur par son nom :

chocolate = Flavour['CHOCOLATE']
chocolate
<Flavour.CHOCOLATE: 1>
Flavour.CHOCOLATE
<Flavour.CHOCOLATE: 1>

Et réciproquement :

chocolate.name
'CHOCOLATE'

IntEnum

En fait, le plus souvent on préfère utiliser IntEnum, une sous-classe de Enum qui permet également de faire des comparaisons. Pour reprendre le cas des codes d’erreur HTTP :

from enum import IntEnum

class HttpError(IntEnum):

    OK = 200
    REDIRECT = 301
    REDIRECT_TMP = 302
    NOT_FOUND = 404
    INTERNAL_ERROR = 500

    # avec un IntEnum on peut faire des comparaisons
    def is_redirect(self):
        return 300 <= self.value <= 399
code = HttpError.REDIRECT_TMP
code.is_redirect()
True

Itération

Un des avantages de cette construction est qu’avec une énumération, l’objet classe (et non une instance) est un itérable :

class Couleur(IntEnum):
    TREFLE = 0
    CARREAU = 1
    COEUR = 2
    PIQUE = 3

    def glyph(self):
        glyphs = {
            Couleur.TREFLE: '\u2663',
            Couleur.CARREAU: '\x1b[31;1m\u2666\x1b[39;0m',
            Couleur.COEUR: '\x1b[31;1m\u2665\x1b[39;0m',
            Couleur.PIQUE: '\u2660',
        }
        return glyphs[self]
for couleur in Couleur:
    print(f"Couleur {couleur} -> {couleur.glyph()}")
Couleur 0 -> ♣
Couleur 1 -> 
Couleur 2 -> 
Couleur 3 -> ♠

Pour en savoir plus

Consultez la documentation officielle du module enum.