Difficulty: Intermediate
What are Python Enums? When and why should you use them over plain constants?
Enum (Python 3.4+) creates a set of symbolic, named constants grouped in a class. Members are instances of the Enum class, not bare integers or strings.
Advantages over constants (STATUS_ACTIVE = 1): - Type safety: passing the wrong value is harder - Auto-complete and IDE support - Iteration, membership testing, comparison - Descriptive __repr__ - Cannot accidentally reuse values (unless using aliases)
Variants: - IntEnum: members compare equal to integers - StrEnum (3.11+): members compare equal to strings - Flag/IntFlag: bitmask operations (|, &, ~) - auto(): auto-generates values
from enum import Enum, auto, Flag
class Status(Enum):
PENDING = auto()
ACTIVE = auto()
INACTIVE = auto()
DELETED = auto()
# Access
print(Status.ACTIVE) # Status.ACTIVE
print(Status.ACTIVE.name) # ACTIVE
print(Status.ACTIVE.value) # 2 (auto starts at 1)
print(repr(Status.ACTIVE)) # <Status.ACTIVE: 2>
# Lookup
print(Status['PENDING']) # Status.PENDING (by name)
print(Status(2)) # Status.ACTIVE (by value)
# Comparison
print(Status.ACTIVE == Status.ACTIVE) # True
print(Status.ACTIVE == Status.INACTIVE) # False
print(Status.ACTIVE == 2) # False! (not IntEnum)
# Iteration
for s in Status:
print(f'{s.name} = {s.value}')
# Membership
print(Status.ACTIVE in Status) # True
# Use in type hints
def update_user(user_id: int, status: Status) -> None:
pass
update_user(1, Status.ACTIVE) # Clear intent
auto() generates sequential values. Enum members do not compare equal to plain integers (use IntEnum for that).
from enum import IntEnum, Flag, auto
# IntEnum: works like int
class Priority(IntEnum):
LOW = 1
MEDIUM = 2
HIGH = 3
print(Priority.HIGH > Priority.LOW) # True
print(Priority.HIGH + 1) # 4 (int arithmetic)
tasks = [
{'name': 'Task A', 'priority': Priority.HIGH},
{'name': 'Task B', 'priority': Priority.LOW},
]
print(sorted(tasks, key=lambda t: t['priority'], reverse=True))
# Flag: bitmask permissions
class Permission(Flag):
READ = auto() # 1
WRITE = auto() # 2
EXECUTE = auto() # 4
ADMIN = READ | WRITE | EXECUTE # 7
user_perms = Permission.READ | Permission.WRITE
print(user_perms) # Permission.READ|WRITE
print(Permission.READ in user_perms) # True
print(Permission.EXECUTE in user_perms) # False
# Toggle permission
user_perms ^= Permission.WRITE # Remove WRITE
print(Permission.WRITE in user_perms) # False
IntEnum inherits from int, enabling arithmetic and comparison with integers. Flag enables bitwise combination of permission flags.
Enum, IntEnum, auto(), Flag, Value/Name