Introdus în Python 3.10 prin PEP 634, Structural Pattern Matching (instrucțiunea match ... case) este mult mai mult decât un simplu switch / case întâlnit în C sau JavaScript. Pe lângă testarea egalității simple, el realizează deconstrucția structurală a datelor (destructuring), potrivind forme complexe de tupluri, liste, dicționare și instanțe de clase, extrăgând automat valorile relevante în variabile locale.
Exemplu practic: Parsarea comenzilor primite dintr-un protocol de rețea
def proceseaza_actiune(comanda):
match comanda:
# Potrivire exactă de comandă fără parametri:
case "iesire" | "quit":
print("Sistem oprit.")
# Deconstrucție de secvență cu lungime fixă și clauză de gardă (guard if):
case ["muta", directie, distanta] if distanta > 0:
print(f"Deplasare în direcția {directie} cu {distanta} metri.")
# Potrivire de comenzi cu număr variabil de parametri (rest unpacking):
case ["notifica", utilizator, *mesaje]:
print(f"Trimitere către {utilizator}: {' '.join(mesaje)}")
# Deconstrucție de dicționar: extrage valorile cheilor specificate
case {"status": "eroare", "cod": cod, "detalii": detalii}:
print(f"Alertă [Cod {cod}]: {detalii}")
# Cazul implicit (Wildcard pattern):
case _:
print(f"Comandă necunoscută sau invalidă: {comanda!r}")
# Testare:
proceseaza_actiune(["muta", "nord", 25])
proceseaza_actiune({"status": "eroare", "cod": 404, "detalii": "Fișier negăsit"})
proceseaza_actiune(["notifica", "dan", "Serverul", "a", "fost", "repornit."])
Deconstrucția Instanțelor de Clase
Pattern matching-ul poate inspecta atributele claselor standard sau ale claselor @dataclass:
Potrivirea obiectelor prin pattern de clasă
from dataclasses import dataclass
@dataclass
class Punct:
x: float
y: float
def localizeaza_punct(punct):
match punct:
case Punct(x=0, y=0):
print("Punctul se află exact în originea (0, 0).")
case Punct(x=0, y=y):
print(f"Punctul se află pe axa Y la cota {y}.")
case Punct(x=x, y=0):
print(f"Punctul se află pe axa X la poziția {x}.")
case Punct(x=x, y=y) if x == y:
print(f"Punctul se află pe prima bisectoare la ({x}, {y}).")
case Punct(x=x, y=y):
print(f"Punct oarecare la coordonatele ({x}, {y}).")
Capcane Frecvente de Evitat
- Numele de variabile captează valori: Dacă scrieți
case status:, Python nu compară cu variabilastatusdin exterior, ci creează o nouă variabilă locală care capturează orice valoare! Pentru a compara cu o constantă definită anterior, folosiți notația cu punct:case Moduri.ACTIV:. - Dicționarele sunt potriviri parțiale: Spre deosebire de liste (unde lungimea trebuie să se potrivească exact),
case {"status": "ok"}:se potrivește chiar dacă dicționarul analizat are și alte chei suplimentare.