How do I use an Enum in Python and why would I?
Short answer
An Enum groups related named constants into a single type, so you use meaningful names instead of loose strings or numbers. It prevents typos and invalid values, and members carry both a name and a value.
The short version
An Enum groups a fixed set of related constants under one type, so you refer to them by meaningful names rather than loose strings or magic numbers. This prevents typos and invalid values, because only the defined members exist. Each member has a name and a value, and members are compared by identity.
Defining and using one
from enum import Enum
class Colour(Enum):
RED = 1
BLUE = 2
GREEN = 3
print(Colour.RED) # Colour.RED
print(Colour.RED.name) # 'RED'
print(Colour.RED.value) # 1
You refer to members as Colour.RED, which is self-documenting and cannot be misspelled without an immediate error.
The problem it solves
Without an enum, people scatter bare strings or numbers through the code.
status = "activ" # typo, silently wrong, no error until much later
A typo like this passes unnoticed and causes a bug far from where it was introduced. With an enum, Status.ACTIV fails immediately with an AttributeError, so the mistake surfaces at once. The enum also documents the full set of valid values in one place.
Looking up by value
You can find a member from its stored value, which is useful when reading data back from a file or database.
Colour(2) # Colour.BLUE
Passing a value that no member has raises ValueError, which is a helpful guard against invalid data.
Comparing members
Enum members are singletons, so compare them with is or == by identity, not by their value.
if colour is Colour.RED:
...
This is clearer than comparing raw numbers and cannot accidentally match an unrelated value that happens to equal 1.
Useful variants
For enums whose members should behave like their values (for example comparing or serialising), IntEnum makes members act as integers, and StrEnum (Python 3.11 and later) makes them act as strings.
from enum import IntEnum
class Priority(IntEnum):
LOW = 1
HIGH = 3
Priority.HIGH > Priority.LOW # True, compares as integers
Use plain Enum by default, and reach for IntEnum or StrEnum only when you specifically need the members to compare or serialise as their underlying value.
Iterating and membership
You can loop over an enum to get all members, which is handy for building menus or validating input.
list(Colour) # [Colour.RED, Colour.BLUE, Colour.GREEN]
"RED" in Colour.__members__ # True
This makes the enum the single source of truth for the valid set, which is the main reason to use one over scattered constants.