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'
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
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()}")
Pour plus de détails, consultez la documentation officielle du module enum.