Lección 12 · 12 de 20
Enumeraciones y match/case · Python
Estados de pedido con Enum y eventos procesados con match/case en Python: patrones de valores, diccionarios, secuencias, capturas y guardas.

Una enumeración (Enum) agrupa un conjunto cerrado de valores con nombre. Status.PAID es mucho más seguro que la cadena "paid": una errata como Status.PIAD falla en el acto. Cada miembro tiene name y value, se puede recorrer con for status in Status y se puede buscar por su valor con Status("paid"). El primer bucle escribe cada miembro con !s (que da Status.PAID) y su valor con !r.
`match` compara un valor con una serie de patrones y ejecuta el primer case que encaja. En next_step, case Status.PENDING: compara con un miembro concreto, y `case _:` recoge todo lo demás, como un else.
En handle los patrones describen la forma de los datos. {"type": "order", "id": oid, ...} encaja con cualquier diccionario que tenga esas claves (aunque tenga más) y captura los valores en oid y total. El if total >= 100 es una guarda: si no se cumple, se prueba el siguiente case, que es el que acepta el pedido 8.
("refund", oid, amount) encaja con cualquier secuencia de tres elementos que empiece por "refund" (tupla o lista; las cadenas no cuentan). ["cancel", *ids] admite cualquier longitud y guarda el resto en la lista ids.
El último evento, "ping", no encaja con nada y cae en case _. {event!r} lo escribe con repr(), entre comillas.
Código · main.py
from enum import Enumclass Status(Enum): PENDING = "pending" PAID = "paid" SHIPPED = "shipped"def next_step(status): match status: case Status.PENDING: return "wait for payment" case Status.PAID: return "pack and ship" case _: # anything else return "nothing to do"def handle(event): match event: # match by shape and capture values case {"type": "order", "id": oid, "total": total} if total >= 100: return f"order {oid}: big order, check stock" case {"type": "order", "id": oid}: return f"order {oid}: accepted" case ("refund", oid, amount): return f"refund {amount} EUR for order {oid}" case ["cancel", *ids]: return f"cancel {len(ids)} orders: {ids}" case _: return f"unknown event: {event!r}"for status in Status: print(f"{status!s:<15} {status.value!r:<10} -> {next_step(status)}")for event in [{"type": "order", "id": 7, "total": 250}, {"type": "order", "id": 8}, ("refund", 7, 40), ["cancel", 3, 4], "ping"]: print(handle(event))Salida · python3 main.py
Status.PENDING 'pending' -> wait for payment Status.PAID 'paid' -> pack and ship Status.SHIPPED 'shipped' -> nothing to do order 7: big order, check stock order 8: accepted refund 40 EUR for order 7 cancel 2 orders: [3, 4] unknown event: 'ping'
Para recordar
Enumda nombres fijos a un conjunto cerrado de valores.matchprueba loscaseen orden y ejecuta el primero que encaja.- Los patrones pueden capturar valores en variables.
ifdespués del patrón añade una condición (guarda).case _:recoge todo lo que no ha encajado.
Ejercicio
Añada un estado CANCELLED a Status y un case en next_step que devuelva "refund the customer"; después, haga que los reembolsos con amount negativo escriban un aviso.