Table des matières

, , ,

Python 3: énumérations

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
 
 
vanilla = Flavour.VANILLA

Les représentations textuelles sont plus parlantes. On peut retrouver une valeur par son nom ou vice versa:

v = Flavour.VANILLA
 
v.value
2
 
v.name
'VANILLA'

IntEnum

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()}")

Complément

Pour plus de détails, consultez la documentation officielle du module enum.