match/case en Python 3.10: pattern matching más allá del switch

Python 3.10 introdujo el structural pattern matching con la PEP 634. La instrucción match/case no es un simple switch: compara la estructura del objeto —no solo su valor— y puede extraer variables del interior en el mismo paso. Es especialmente útil para parsear respuestas de API, implementar CLIs y escribir máquinas de estado.

Sintaxis básica y patrones de valor

def clasificar_http(codigo):
    match codigo:
        case 200:
            return "OK"
        case 404:
            return "No encontrado"
        case 500 | 502 | 503:  # patrón OR
            return "Error de servidor"
        case _:               # caso por defecto (wildcard)
            return f"Código desconocido: {codigo}"

print(clasificar_http(404))  # No encontrado
print(clasificar_http(502))  # Error de servidor

Patrones de secuencia

def procesar_comando(tokens):
    match tokens:
        case ["salir"]:
            return "Cerrando..."
        case ["ayuda"]:
            return "Comandos: salir, ayuda, listar"
        case ["listar", directorio]:
            return f"Listando: {directorio}"
        case ["mover", origen, destino]:
            return f"Moviendo {origen} ? {destino}"
        case ["buscar", *terminos]:  # resto en lista
            return f"Buscando: {' '.join(terminos)}"
        case _:
            return "Comando no reconocido"

print(procesar_comando(["listar", "/home"]))
# Listando: /home
print(procesar_comando(["mover", "a.txt", "b.txt"]))
# Moviendo a.txt ? b.txt

Patrones de mapping (diccionarios)

def manejar_evento(evento):
    match evento:
        case {"tipo": "click", "boton": boton, "x": x, "y": y}:
            return f"Click con botón {boton} en ({x}, {y})"
        case {"tipo": "teclado", "tecla": tecla}:
            return f"Tecla pulsada: {tecla}"
        case {"tipo": tipo}:
            return f"Evento desconocido: {tipo}"
        case _:
            return "Evento sin tipo"

print(manejar_evento({"tipo": "click", "boton": 1, "x": 100, "y": 200}))
# Click con botón 1 en (100, 200)

Patrones de clase

from dataclasses import dataclass

@dataclass
class Punto:
    x: float
    y: float

@dataclass
class Circulo:
    centro: Punto
    radio: float

def describir_forma(forma):
    match forma:
        case Punto(x=0, y=0):
            return "Punto en el origen"
        case Punto(x=x, y=0):
            return f"Punto en el eje X: ({x}, 0)"
        case Punto(x=x, y=y):
            return f"Punto genérico: ({x}, {y})"
        case Circulo(radio=r) if r > 10:
            return f"Círculo grande (r={r})"
        case Circulo(radio=r):
            return f"Círculo pequeño (r={r})"

print(describir_forma(Punto(3, 0)))          # Punto en el eje X: (3, 0)
print(describir_forma(Circulo(Punto(0,0), 15)))  # Círculo grande (r=15)

Guards: añadir condiciones con if

def clasificar_temperatura(temp):
    match temp:
        case t if t < 0:
            return f"{t}°C — bajo cero"
        case t if t < 20:
            return f"{t}°C — frío"
        case t if t < 30:
            return f"{t}°C — agradable"
        case t:
            return f"{t}°C — calor"

print(clasificar_temperatura(-5))   # -5°C — bajo cero
print(clasificar_temperatura(25))   # 25°C — agradable

Máquina de estados con match/case

estado = "inicio"

def transicion(estado, evento):
    match (estado, evento):
        case ("inicio", "conectar"):
            return "conectado"
        case ("conectado", "autenticar"):
            return "autenticado"
        case ("autenticado", "desconectar") | ("conectado", "desconectar"):
            return "inicio"
        case _:
            return estado  # sin transición

estado = transicion(estado, "conectar")     # conectado
estado = transicion(estado, "autenticar")   # autenticado
estado = transicion(estado, "desconectar")  # inicio
print(estado)  # inicio

match/case destaca cuando la estructura del dato es el criterio de decisión, no solo su valor. Si solo comparas un entero o cadena con un conjunto fijo de literales, un diccionario de dispatch sigue siendo más simple.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP