Skip to main content Brad's PyNotes

Enum Module: Create Robust Enumerations for Cleaner Code

TL;DR

The enum module provides Enum, IntEnum, Flag, and auto() for creating robust enumerations that replace magic numbers and strings with type-safe, self-documenting constants.

Interesting!

Python enums are not just constants - they’re full classes with methods, and enum members are singletons, meaning Color.RED is Color.RED always returns True, making identity checks extremely fast.

Basic Enumerations

python code snippet start

from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

# Usage
print(Color.RED)        # Color.RED
print(Color.RED.name)   # RED
print(Color.RED.value)  # 1

# Comparison works
favorite = Color.BLUE
if favorite == Color.BLUE:
    print("Blue is beautiful!")

# Iteration
for color in Color:
    print(f"{color.name}: {color.value}")

python code snippet end

Auto-Generated Values

python code snippet start

from enum import Enum, auto

class Status(Enum):
    PENDING = auto()
    APPROVED = auto()
    REJECTED = auto()
    CANCELLED = auto()

print(Status.PENDING.value)   # 1
print(Status.APPROVED.value)  # 2

# String values with auto
class Direction(Enum):
    def _generate_next_value_(name, start, count, last_values):
        return name.lower()
    
    NORTH = auto()  # 'north'
    SOUTH = auto()  # 'south'
    EAST = auto()   # 'east'
    WEST = auto()   # 'west'

python code snippet end

Functional API

python code snippet start

from enum import Enum

# Create enum using functional API
HttpStatus = Enum('HttpStatus', 'OK NOT_FOUND SERVER_ERROR')
print(HttpStatus.OK)        # HttpStatus.OK
print(HttpStatus.OK.value)  # 1

# With custom values
HttpStatus = Enum('HttpStatus', {
    'OK': 200,
    'NOT_FOUND': 404,
    'SERVER_ERROR': 500
})
print(HttpStatus.NOT_FOUND.value)  # 404

python code snippet end

IntEnum for Numeric Compatibility

python code snippet start

from enum import IntEnum

class Priority(IntEnum):
    LOW = 1
    MEDIUM = 2
    HIGH = 3
    CRITICAL = 4

# Can be used in numeric operations
task_priority = Priority.HIGH
if task_priority > Priority.MEDIUM:
    print("High priority task!")

# Works with comparison to regular integers
if task_priority >= 3:
    print("Priority level 3 or higher")

# Sorting works naturally
priorities = [Priority.LOW, Priority.CRITICAL, Priority.MEDIUM]
sorted_priorities = sorted(priorities)
print(sorted_priorities)  # [Priority.LOW, Priority.MEDIUM, Priority.CRITICAL]

python code snippet end

Flag Enums for Bitwise Operations

python code snippet start

from enum import Flag, auto

class Permission(Flag):
    READ = auto()
    WRITE = auto()
    EXECUTE = auto()

# Combine permissions
user_perms = Permission.READ | Permission.WRITE
print(user_perms)  # Permission.WRITE|READ

# Check permissions
if Permission.READ in user_perms:
    print("User can read")

if user_perms & Permission.WRITE:
    print("User can write")

# All permissions
admin_perms = Permission.READ | Permission.WRITE | Permission.EXECUTE
print(admin_perms)  # Permission.EXECUTE|WRITE|READ

python code snippet end

Practical Examples

HTTP Status Codes

python code snippet start

from enum import Enum

class HTTPStatus(Enum):
    OK = 200
    CREATED = 201
    BAD_REQUEST = 400
    UNAUTHORIZED = 401
    NOT_FOUND = 404
    SERVER_ERROR = 500
    
    def __str__(self):
        return f"{self.value} {self.name.replace('_', ' ').title()}"
    
    @property
    def is_success(self):
        return 200 <= self.value < 300
    
    @property
    def is_client_error(self):
        return 400 <= self.value < 500

# Usage
status = HTTPStatus.NOT_FOUND
print(status)              # 404 Not Found
print(status.is_success)   # False
print(status.is_client_error)  # True

python code snippet end

Game States

python code snippet start

from enum import Enum, auto

class GameState(Enum):
    MENU = auto()
    PLAYING = auto()
    PAUSED = auto()
    GAME_OVER = auto()
    
    def can_transition_to(self, new_state):
        transitions = {
            GameState.MENU: [GameState.PLAYING],
            GameState.PLAYING: [GameState.PAUSED, GameState.GAME_OVER],
            GameState.PAUSED: [GameState.PLAYING, GameState.MENU],
            GameState.GAME_OVER: [GameState.MENU, GameState.PLAYING]
        }
        return new_state in transitions.get(self, [])

# Usage
current_state = GameState.MENU
if current_state.can_transition_to(GameState.PLAYING):
    print("Starting game!")

python code snippet end

Configuration Settings

python code snippet start

from enum import Enum

class LogLevel(Enum):
    DEBUG = 10
    INFO = 20
    WARNING = 30
    ERROR = 40
    CRITICAL = 50
    
    def __ge__(self, other):
        if self.__class__ is other.__class__:
            return self.value >= other.value
        return NotImplemented
    
    def __gt__(self, other):
        if self.__class__ is other.__class__:
            return self.value > other.value
        return NotImplemented

class Config(Enum):
    LOG_LEVEL = LogLevel.INFO
    MAX_RETRIES = 3
    TIMEOUT = 30
    
    @classmethod
    def get(cls, key, default=None):
        try:
            return cls[key].value
        except KeyError:
            return default

# Usage
if LogLevel.DEBUG >= Config.LOG_LEVEL.value:
    print("Debug logging enabled")

python code snippet end

Advanced Features

Unique Decorator

python code snippet start

from enum import Enum, unique

@unique
class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3
    # CRIMSON = 1  # This would raise ValueError due to @unique

# Aliases (when you want them)
class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3
    CRIMSON = 1  # Alias for RED

print(Color.RED is Color.CRIMSON)  # True

python code snippet end

Custom Methods

python code snippet start

from enum import Enum

class Planet(Enum):
    MERCURY = (3.303e+23, 2.4397e6)
    VENUS   = (4.869e+24, 6.0518e6)
    EARTH   = (5.976e+24, 6.37814e6)
    MARS    = (6.421e+23, 3.3972e6)
    
    def __init__(self, mass, radius):
        self.mass = mass       # in kilograms
        self.radius = radius   # in meters
    
    @property
    def surface_gravity(self):
        # universal gravitational constant
        G = 6.67300E-11
        return G * self.mass / (self.radius * self.radius)

print(Planet.EARTH.surface_gravity)  # 9.802652743337129

python code snippet end

Best Practices

python code snippet start

# Use enums instead of constants
# Bad
STATUS_PENDING = 1
STATUS_APPROVED = 2
STATUS_REJECTED = 3

# Good
class Status(Enum):
    PENDING = 1
    APPROVED = 2
    REJECTED = 3

# Use meaningful names and values
class ResponseFormat(Enum):
    JSON = "application/json"
    XML = "application/xml"
    HTML = "text/html"

# Group related constants
class DatabaseSettings(Enum):
    HOST = "localhost"
    PORT = 5432
    DATABASE = "myapp"
    TIMEOUT = 30

python code snippet end

The enum module transforms magic numbers and strings into self-documenting, type-safe code that’s easier to maintain and debug. Use enums with type annotations for better static analysis and class design patterns . Combine with database operations for status tracking and JSON serialization for API responses.

Reference: Python Enum Module Documentation