Also essential: enum module docs. PEP 634 has the full pattern matching spec if you want deep detail.
Python's enum.Enum is your TypeScript enum or const union — a fixed set of named constants. Use them instead of magic strings or numbers.
// String union (preferred)
type Direction = "north" | "south" | "east" | "west";
// Enum
enum Status {
Pending = "pending",
Active = "active",
Closed = "closed",
}
const s = Status.Active;
console.log(s); // "active"
console.log(s === "active"); // true
from enum import Enum, auto
class Direction(Enum):
NORTH = "north"
SOUTH = "south"
EAST = "east"
WEST = "west"
class Status(Enum):
PENDING = "pending"
ACTIVE = "active"
CLOSED = "closed"
s = Status.ACTIVE
print(s) # Status.ACTIVE
print(s.value) # "active"
print(s.name) # "ACTIVE"
print(s == Status.ACTIVE) # True
print(s == "active") # False! Enum ≠ its value
# auto() — auto-assign integer values
class Color(Enum):
RED = auto() # 1
GREEN = auto() # 2
BLUE = auto() # 3
# Iterate members
for direction in Direction:
print(direction.name, direction.value)
# Look up by value
Status("active") # Status.ACTIVE
Status["ACTIVE"] # Status.ACTIVE ← by name
# Membership check
"active" in [s.value for s in Status] # True
# IntEnum — comparisons work with plain ints
from enum import IntEnum
class Priority(IntEnum):
LOW = 1
MEDIUM = 2
HIGH = 3
Priority.HIGH > Priority.LOW # True
Priority.HIGH > 2 # True ← int comparison works
# Flag — bitwise combination (like Unix permissions)
from enum import Flag
class Permission(Flag):
READ = auto()
WRITE = auto()
EXECUTE = auto()
ALL = READ | WRITE | EXECUTE
perm = Permission.READ | Permission.WRITE
Permission.READ in perm # True
Python 3.10+ finally has a switch statement — but far more powerful. It matches structure, not just equality.
switch (status) {
case "pending":
handlePending();
break;
case "active":
handleActive();
break;
default:
throw new Error("Unknown status");
}
match status:
case "pending":
handle_pending()
case "active":
handle_active()
case _: # default / wildcard
raise ValueError(f"Unknown: {status}")
# No break needed — cases don't fall through
match/case goes far beyond switch — it can destructure sequences, dicts, and classes.
match command:
case "quit":
sys.exit(0)
case "help":
print_help()
case "version":
print("1.0.0")
match status_code:
case 200 | 201 | 204:
print("Success")
case 400 | 422:
print("Client error")
case 500 | 502 | 503:
print("Server error")
point = (3, 4)
match point:
case (0, 0):
print("Origin")
case (x, 0):
print(f"On x-axis at {x}") # x is captured!
case (0, y):
print(f"On y-axis at {y}")
case (x, y):
print(f"At ({x}, {y})") # both captured
def handle_event(event: dict):
match event:
case {"type": "click", "x": x, "y": y}:
print(f"Click at ({x}, {y})")
case {"type": "keydown", "key": key}:
print(f"Key pressed: {key}")
case {"type": t}:
print(f"Unknown event type: {t}")
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
@dataclass
class Circle:
center: Point
radius: float
def describe(shape):
match shape:
case Circle(center=Point(x=0, y=0), radius=r):
print(f"Circle at origin, radius {r}")
case Circle(center=Point(x=x, y=y), radius=r):
print(f"Circle at ({x},{y}), radius {r}")
case _:
print("Unknown shape")
match value:
case x if x < 0:
print(f"Negative: {x}")
case x if x == 0:
print("Zero")
case x if x > 0:
print(f"Positive: {x}")
from enum import Enum
class Direction(Enum):
NORTH = "north"
SOUTH = "south"
EAST = "east"
WEST = "west"
def move(direction: Direction, steps: int = 1):
match direction:
case Direction.NORTH:
y += steps
case Direction.SOUTH:
y -= steps
case Direction.EAST:
x += steps
case Direction.WEST:
x -= steps
1. Status.ACTIVE == "active" when Status is an Enum?
2. In a match/case, does Python fall through to the next case like JavaScript's switch?
3. In case (x, 0):, what does x do?
4. What does Permission.READ | Permission.WRITE produce with Flag?
Questions answered correctly.