Construcția match
Începând cu versiunea 3.10, în limbajul Python a apărut funcționalitatea de pattern matching (potrivirea cu șabloane). Pattern matching reprezintă utilizarea construcției match, care permite compararea unei expresii cu un anumit șablon. Dacă expresia corespunde șablonului, se execută anumite acțiuni. În acest sens, construcția match este similară cu construcția if/else/elif, care execută anumite acțiuni în funcție de o condiție.
Totuși, funcționalitatea match este mult mai largă - permite, de asemenea, extragerea datelor din tipuri compuse și aplicarea de acțiuni asupra diferitelor părți ale obiectelor.
Construcția match are următoarea definiție formală:
match expresie:
case șablon_1:
acțiune_1
case șablon_2:
acțiune_2
................
case șablon_N:
acțiune_N
case _:
acțiune_implicită
După cuvântul cheie match urmează expresia care urmează să fie comparată. Apoi, după două puncte, pe liniile următoare se află expresiile case. După fiecare expresie case este specificat un șablon, cu care expresia din match este comparată. După șablon, se specifică setul de acțiuni ale blocului case.
Construcția match compară secvențial expresia cu șabloanele din blocurile case. Dacă se găsește un șablon dintr-un bloc case care corespunde expresiei din match, se execută instrucțiunile din acel bloc case.
Ca șabloane, cu care sunt comparate expresiile, pot fi utilizate atât date de tipuri primitive, cât și secvențe de elemente și obiecte ale claselor.
Să luăm un exemplu în care șablonul este reprezentat de litere de tipuri primitive. De exemplu, în funcție de limbă, vom afișa un mesaj de bun venit:
def print_hello(language):
match language:
case "romanian":
print("Salut")
case "english":
print("Hello")
case "german":
print("Hallo")
print_hello("english") # Hello
print_hello("german") # Hallo
print_hello("romanian") # Salut
Aici, funcția print_hello primește un parametru language, prin care se transmite limba selectată. În funcția propriu-zisă, construcția match compară valoarea variabilei language. În blocurile case, sunt definite șabloane - șiruri de caractere cu care variabila language este comparată.
De exemplu, la apelarea print_hello("english"), parametrul language este egal cu "english", astfel că construcția match va selecta următorul bloc case:
case "english":
print("Hello")
Observați că blocurile case au indentare față de începutul construcției match, iar instrucțiunile fiecărui bloc case au indentare față de începutul acelui bloc case. Dacă un bloc case conține o singură instrucțiune, aceasta poate fi plasată pe aceeași linie cu operatorul case:
def print_hello(language):
match language:
case "romanian": print("Salut")
case "english": print("Hello")
case "german": print("Hallo")
print_hello("english") # Hello
print_hello("german") # Hallo
print_hello("romanian") # Salut
Dacă expresia din match nu corespunde nici unuia dintre șabloanele case, niciunul dintre aceste blocuri case nu se execută.
Dacă este necesar ca la neconcordanța valorilor (dacă nici unul dintre șabloanele case nu corespunde expresiei match) să fie executate anumite acțiuni implicite, se folosește șablonul _ (underscore):
def print_hello(language):
match language:
case "romanian":
print("Salut")
case "english":
print("Hello")
case "german":
print("Hallo")
case _:
print("Undefined")
print_hello("english") # Hello
print_hello("spanish") # Undefined
Dacă niciunul dintre șabloanele case nu corespunde valorii language, se va executa blocul:
case _:
print("Undefined")
Se poate defini și un bloc case care să permită compararea simultană cu mai multe valori. În acest caz, valorile sunt separate de o linie verticală:
def print_hello(language):
match language:
case "romanian":
print("Salut")
case "american english" | "british english" | "english":
print("Hello")
case _:
print("Undefined")
print_hello("english") # Hello
print_hello("american english") # Hello
print_hello("spanish") # Undefined
În acest caz, șablonul case "american english" | "british english" | "english" corespunde simultan celor trei valori.
În mod similar, se pot compara expresii cu date de alte tipuri. De exemplu:
def operation(a, b, code):
match code:
case 1:
return a + b
case 2:
return a - b
case 3:
return a * b
case _:
return 0
print(operation(10, 5, 1)) # 15
print(operation(10, 5, 2)) # 5
print(operation(10, 5, 3)) # 50
print(operation(10, 5, 4)) # 0
Aici, funcția operation primește două numere și un cod de operație. Construcția match compară codul operației cu valori specifice și, în funcție de valoare, execută o anumită operație asupra numerelor. De exemplu, dacă code este egal cu 1, se execută expresia:
case 1:
return a + b
Această expresie case va returna suma numerelor a și b
Similar, dacă code = 2, se returnează diferența, iar dacă code = 3, se returnează produsul numerelor. În toate celelalte cazuri, se returnează 0.