Skip to lesson
Python for JS Developers

Modern PythonLesson 3 of 3

Pattern Matching & Enums

3 min

Python 3.10 introduced match/case. It looks like switch/case but is far more powerful: it can destructure sequences, match dictionary shapes, check types and attributes of objects, and add guard conditions, all in one construct.

There is no fall-through. Each case is independent, as if every case ended with break. The wildcard pattern _ plays the role of default. You can combine alternatives with |, as in case "y" | "yes":.

The biggest trap: a bare name in a pattern is a capture, not a comparison. case RED: does not compare against a variable called RED; it matches anything and assigns it to RED. To compare against a constant, use a dotted name such as Color.RED or a literal.

Python also has real Enums, unlike JS where "enums" are usually frozen objects (TypeScript's enum is a compile-time feature). Python Enums are classes: members have a name and a value, the enum is iterable, members are singletons you can compare with is, and typos raise AttributeError instead of silently producing undefined. StrEnum (3.11+) gives you members that are also real strings, which is handy for JSON and APIs.

Quick reference

JavaScriptPythonNote
switch (x) { case 1: ... break }match x: case 1:No break, no fall-through
default:case _:Wildcard pattern
case 'y': case 'yes':case "y" | "yes":Or-patterns
No destructuring in switchcase [cmd, arg]:Sequence patterns
if (e.type === 'click')case {"type": "click", "x": x}:Mapping patterns
No guard clausecase [x, y] if x > y:Guards
Object.freeze({ A: 'a' })class E(Enum): A = 'a'Real enum type

Side by side

JavaScript
// JavaScript
switch (status) {
  case "active": handleActive(); break;
  case "inactive": handleInactive(); break;
  default: handleUnknown();
}

const Status = Object.freeze({
  ACTIVE: "active",
  INACTIVE: "inactive",
});
Python
# Python match/case (3.10+)
match status:
    case "active":
        handle_active()
    case "inactive" | "disabled":
        handle_inactive()
    case _:
        handle_unknown()

# Sequence patterns
match command.split():
    case ["go", direction]:
        move(direction)
    case ["pick", "up", item]:
        pickup(item)

# Mapping patterns + guards
match event:
    case {"type": "click", "x": x, "y": y}:
        handle_click(x, y)
    case {"type": "key", "key": k} if k in VALID:
        handle_key(k)

# Enums
from enum import Enum, StrEnum, auto
class Color(Enum):
    RED = auto()
    GREEN = auto()

class Status(StrEnum):
    ACTIVE = "active"

for c in Color:
    print(c)          # Color.RED, Color.GREEN

Exercise

Real Python, running in your browser

Write using match/case and Enum:

1. Enum HttpMethod with members GET, POST, PUT, DELETE 2. Function handle_request(method, path) using match: - GET + "/users" -> "list users" - GET + any other path -> "get " + path - POST + "/users" -> "create user" - DELETE + any path -> "delete " + path - anything else -> "405 Not Allowed"

Ctrl + Enter runCtrl + Shift + Enter checkTab indentEsc then Tab to leave the editorCtrl + / comment