Python Enums: The enum Module
· 3 min read · Updated March 13, 2026 · beginner
python stdlib enum constants best-practices
Enums (enumerations) are a way to define a set of named constant values. The Python enum module provides tools for creating enumerations, which are useful when you have a fixed set of related values that have semantic meaning in your code.
Why Use Enums?
Without enums, developers often use magic numbers or strings:
# Bad: magic numbers
status = 1 # What does 1 mean?
# Bad: magic strings
status = "active" # Typos won't be caught
Enums solve these problems by providing:
- Type safety: IDEs can warn about invalid values
- Readability: Code reads like English
- Immutability: Values cannot be changed accidentally
- Organization: Related constants are grouped together
Creating Your First Enum
from enum import Enum
class Status(Enum):
PENDING = 1
APPROVED = 2
REJECTED = 3
# Accessing enum members
print(Status.PENDING) # Status.PENDING
print(Status.PENDING.name) # PENDING
print(Status.PENDING.value) # 1
Comparing Enums
Enum members are compared by identity, not value:
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
print(Color.RED == Color.RED) # True
print(Color.RED == 1) # False (different types)
print(Color(2)) # Color.GREEN (value to enum)
print(Color['GREEN']) # Color.GREEN (name to enum)
Auto-Numbering Enums
Use auto to let Python assign values:
from enum import Enum, auto
class Direction(Enum):
NORTH = auto()
SOUTH = auto()
EAST = auto()
WEST = auto()
print([d.value for d in Direction]) # [1, 2, 3, 4]
Enum Methods
Enums provide useful methods:
from enum import Enum
class Status(Enum):
PENDING = "pending"
APPROVED = "approved"
REJECTED = "rejected"
# Iterate over all members
for status in Status:
print(f"{status.name}: {status.value}")
# Get enum from value
status = Status("approved")
print(status) # Status.APPROVED
# Check if value exists
print("approved" in Status._value2member_map_) # True
Flag Enums for Combinations
Use Flag when you need combinable bitwise values:
from enum import Flag, auto
class Permission(Flag):
READ = auto()
WRITE = auto()
EXECUTE = auto()
# Combine permissions
admin = Permission.READ | Permission.WRITE | Permission.EXECUTE
print(admin) # Permission.READ|WRITE|EXECUTE
print(Permission.READ in admin) # True
IntEnum: Enums That Behave Like Integers
For cases where you need enum compatibility with integers:
from enum import IntEnum
class HTTPStatus(IntEnum):
OK = 200
NOT_FOUND = 404
SERVER_ERROR = 500
# Works like an integer
print(HTTPStatus.OK == 200) # True
print(HTTPStatus.OK + 1) # 201
Enum with Methods
You can add methods to enum classes:
from enum import Enum
class Level(Enum):
LOW = 1
MEDIUM = 2
HIGH = 3
def describe(self):
return f"{self.name} (value: {self.value})"
@property
def is_critical(self):
return self == Level.HIGH
print(Level.HIGH.describe()) # HIGH (value: 3)
print(Level.HIGH.is_critical) # True
Best Practices
- Use PascalCase for enum names:
Status,Color,Direction - Use UPPER_SNAKE_CASE for members:
PENDING,ACTIVE,DONE - Prefer enums over constants: Type safety is worth the extra typing
- Use
auto()for simple sequences: Less maintenance when reordering
Common Gotchas
from enum import Enum
# Aliases - avoid this!
class BadEnum(Enum):
A = 1
B = 2
C = 1 # This creates an alias!
print(BadEnum.C) # BadEnum.A (not BadEnum.C!)
print(BadEnum.C is BadEnum.A) # True
# Use enum.unique to catch this
from enum import unique, Enum
@unique
class GoodEnum(Enum):
A = 1
B = 2
# C = 1 # Would raise ValueError
When to Use Enums
- Status codes and states
- Configuration options
- Menu items or commands
- Days of the week, months
- Any fixed set of related values
See Also
remodule — Regular expression operations for pattern matchingdataclassesmodule — Data classes for structured datatypingmodule — Type hints for better code documentation