Site

Enums — Python Enumeration Types

Tutorial 8.0  •  Python / Learn

8.0 What This Teaches

This tutorial covers Python's enum module: Python enums are full objects with names, values, and methods. Rust enums can carry associated data per variant. C# enums are typed integer constants.

8.1 Basic Enum

from enum import Enum

class Direction(Enum):
    NORTH = 1
    SOUTH = 2
    EAST  = 3
    WEST  = 4

d = Direction.NORTH
print(d)         # Direction.NORTH
print(d.name)    # NORTH
print(d.value)   # 1
print(d is Direction.NORTH)   # True
Enum members are instances of the class. Access them by name through the class. Two references to the same member are always identical (is).

8.2 IntEnum and StrEnum

IntEnum members compare equal to integers of the same value. StrEnum members compare equal to their string values. Use these when you need to interoperate with APIs expecting plain ints or strings:
from enum import IntEnum, StrEnum

class HttpStatus(IntEnum):
    OK          = 200
    CREATED     = 201
    NOT_FOUND   = 404
    SERVER_ERROR = 500

print(HttpStatus.OK == 200)      # True (IntEnum)
print(HttpStatus.NOT_FOUND > 400)  # True

class Color(StrEnum):
    RED   = "red"
    GREEN = "green"
    BLUE  = "blue"

print(Color.RED == "red")   # True
print(f"color is {Color.BLUE}")  # color is blue

8.3 auto() for Automatic Values

auto() assigns values automatically. For plain Enum it assigns 1, 2, 3 … For StrEnum it uses the lowercase member name:
from enum import Enum, auto

class Season(Enum):
    SPRING = auto()
    SUMMER = auto()
    AUTUMN = auto()
    WINTER = auto()

for s in Season:
    print(s.name, s.value)
# SPRING 1, SUMMER 2, AUTUMN 3, WINTER 4

8.4 Flag Enums

Flag members represent bits. Combine them with | and test membership with in:
from enum import Flag, auto

class Permission(Flag):
    READ    = auto()   # 1
    WRITE   = auto()   # 2
    EXECUTE = auto()   # 4
    ALL     = READ | WRITE | EXECUTE

p = Permission.READ | Permission.WRITE
print(p)                         # Permission.READ|WRITE
print(Permission.READ in p)      # True
print(Permission.EXECUTE in p)   # False

p |= Permission.EXECUTE
print(p)                         # Permission.READ|WRITE|EXECUTE

8.5 Iteration and Lookup

from enum import Enum

class Planet(Enum):
    MERCURY = 3.3e23
    VENUS   = 4.87e24
    EARTH   = 5.97e24
    MARS    = 6.39e23

# Iterate all members
for p in Planet:
    print(f"{p.name}: mass={p.value:.2e} kg")

# Look up by value
print(Planet(5.97e24))   # Planet.EARTH

# Look up by name
print(Planet["MARS"])    # Planet.MARS

8.6 Example - All Together

# Enums - traffic light state machine with match statement.

from enum import Enum, auto

class TrafficLight(Enum):
    RED    = auto()
    YELLOW = auto()
    GREEN  = auto()

def describe(light: TrafficLight) -> str:
    match light:
        case TrafficLight.RED:    return "STOP"
        case TrafficLight.YELLOW: return "CAUTION"
        case TrafficLight.GREEN:  return "GO"

def next_light(light: TrafficLight) -> TrafficLight:
    match light:
        case TrafficLight.RED:    return TrafficLight.GREEN
        case TrafficLight.GREEN:  return TrafficLight.YELLOW
        case TrafficLight.YELLOW: return TrafficLight.RED

light = TrafficLight.RED
for _ in range(6):
    print(describe(light))
    light = next_light(light)
Expected output:
STOP
GO
CAUTION
STOP
GO
CAUTION

8.7 Exercise

Exercise
  • Define a Season enum with auto() values. Use a match statement to map each season to a weather description.
  • Define a Permission Flag enum with READ, WRITE, and EXECUTE. Create several permission combinations and test whether each includes READ.
  • Iterate all members of a Planet IntEnum and print each planet's name and integer value.

8.8 Common Mistakes

Comparing enum members with ==

from enum import Enum

class Color(Enum):
    RED = 1

print(Color.RED == 1)   # False for plain Enum (use IntEnum if you need this)
print(Color.RED is Color.RED)  # True - use identity for same-member tests
Plain Enum members are not equal to their values. Use IntEnum or StrEnum when comparison with raw values is needed.

Using plain integers for bit flags instead of Flag

Combining plain integer constants loses the type name in printed output and makes code less readable. Use Flag for bit-field values.

Reusing an enum value by accident

class Status(Enum):
    PENDING  = 1
    ACTIVE   = 1   # not a new member - it's an alias for PENDING!

print(list(Status))  # [<Status.PENDING: 1>] - ACTIVE is not listed
Duplicate values create aliases, not new members. Use auto() or @unique decorator to prevent accidental aliases.

8.9 Key Terms

TermMeaning
EnumBase class for enumerations; members are instances with .name and .value
IntEnumEnum subtype whose members compare equal to integers
StrEnumEnum subtype whose members compare equal to their string values
FlagEnum subtype supporting bitwise combination with | and in
auto()Assigns the next sequential value automatically
.nameString name of an enum member
.valueThe value assigned to an enum member
aliasTwo enum members with the same value; only the first is listed
@uniqueDecorator that raises ValueError if any duplicate values exist