Jak używać strukturalnego dopasowywania wzorców w Pythonie

Składnia dopasowywania wzorców wprowadzona w Pythonie 3.10 pozwala na nowe, wydajne techniki programistyczne do podejmowania decyzji w aplikacjach.

Jak używać strukturalnego dopasowywania wzorców w Pythonie

robynmac / Getty Images

Python, przy całej swojej potędze i popularności, długo nie posiadał formy kontroli przepływu, którą można znaleźć w innych językach - sposobu na wzięcie wartości i eleganckie dopasowanie jej do jednego z wielu możliwych warunków. W C i C++ jest to konstrukcja switch/case; w Rust nazywa się to „pattern matching”.

Tradycyjne sposoby robienia tego w Pythonie nie są eleganckie. Jednym z nich jest pisanie łańcuchów wyrażeń if/elif/else. Innym jest przechowywanie wartości do dopasowania jako kluczy w słowniku, a następnie użycie tych wartości do podjęcia akcji - np. przechowywanie funkcji jako wartości i użycie klucza lub innej zmiennej jako wejścia. W wielu przypadkach działa to dobrze, ale może być kłopotliwe w budowie i utrzymaniu. Po tym, jak wiele propozycji dodania do Pythona składni podobnej do switch/case nie powiodło się, ostatnia propozycja twórcy języka Python, Guido van Rossuma i wielu innych współtwórców, została zaakceptowana dla Pythona 3.10: strukturalne dopasowywanie wzorców. Strukturalne dopasowywanie wzorców nie tylko umożliwia wykonywanie prostych dopasowań w stylu switch/case, ale także wspiera szerszy zakres przypadków użycia.

Zobacz również:

  • Premiera GitHub Copilot Enterprise

Poniżej krótki tutorial video:

Wprowadzenie do strukturalnego dopasowywania wzorców w Pythonie

Strukturalne dopasowywanie wzorców wprowadza do Pythona instrukcję match/case oraz składnię wzorca. Instrukcja match/case ma taki sam podstawowy zarys jak switch/case. Pobiera obiekt, testuje go względem jednego lub więcej wzorców dopasowania i wykonuje akcję, jeśli znajdzie dopasowanie.

Jak używać strukturalnego dopasowywania wzorców w Pythonie

Po każdej instrukcji case następuje wzorzec dopasowania. W powyższym przykładzie używamy prostych łańcuchów jako celów dopasowania, ale możliwe są bardziej złożone dopasowania.

Python wykonuje dopasowania, przechodząc przez listę przypadków od góry do dołu. Przy pierwszym dopasowaniu Python wykonuje instrukcje w odpowiadającym im bloku przypadków, a następnie przeskakuje na koniec bloku dopasowania i kontynuuje dalszą część programu. Nie ma „przejścia”między przypadkami, ale możliwe jest zaprojektowanie logiki tak, aby obsługiwała wiele możliwych przypadków w jednym bloku case.

Możliwe jest także przechwycenie całości lub części dopasowania i ponowne jego użycie. W przypadku unknown_command w naszym przykładzie powyżej, wartość jest „przechwytywana” w zmiennej unknown_command, więc możemy jej ponownie użyć.

Dopasowywanie do zmiennych za pomocą strukturalnego dopasowywania wzorców Pythona

Ważna uwaga jest warta podniesienia tutaj. Jeśli wymieniasz nazwy zmiennych w instrukcji case, nie oznacza to, że dopasowanie powinno być wykonane względem zawartości nazwanej zmiennej. Zmienne w case są używane do przechwytywania wartości, która jest dopasowywana.

Jeśli chcesz dokonać dopasowania do zawartości zmiennej, zmienna ta musi być wyrażona jako nazwa z kropką, jak enum. Oto przykład:

Jak używać strukturalnego dopasowywania wzorców w Pythonie

Nie trzeba używać enum, wystarczy dowolna nazwa właściwości z kropką. Niemniej jednak, enumy są najbardziej znanym i idiomatycznym sposobem na zrobienie tego w Pythonie.

Dopasowywanie do wielu elementów za pomocą strukturalnego dopasowywania wzorców Pythona

Kluczem do najefektywniejszej pracy z dopasowywaniem wzorców nie jest używanie go jako substytutu wyszukiwania słownikowego. Chodzi o to, aby opisać strukturę tego, co chcemy dopasować. W ten sposób, możesz wykonać dopasowanie na podstawie liczby elementów, które dopasowujesz, lub ich kombinacji.

Oto nieco bardziej złożony przykład. Użytkownik wpisuje tutaj polecenie, po którym opcjonalnie następuje nazwa pliku.

Jak używać strukturalnego dopasowywania wzorców w Pythonie

Przyjrzyjmy się temu krok po kroku:

case ["quit"]: testuje czy to, do czego dopasowujemy jest listą zawierającą tylko element "quit", uzyskany z podziału wejścia.

case ["load", filename]: testuje czy pierwszym dzielonym elementem jest łańcuch "load", i czy występuje po nim drugi łańcuch. Jeśli tak, to przechowujemy ten drugi łańcuch w zmiennej nazwa_pliku i używamy go do dalszej pracy. To samo dla przypadku ["save", filename]:.

case _: jest dopasowaniem wieloznacznym. Pasuje, jeśli do tego momentu nie dokonano żadnego innego dopasowania. Zauważ, że zmienna podkreślenia, _, nie wiąże się w rzeczywistości z niczym; nazwa _ jest używana jako sygnał dla polecenia match, że dany przypadek jest wieloznaczny. (To dlatego odnosimy się do polecenia zmiennej w ciele bloku case; nic nie zostało przechwycone).

Wzorce w Pythonie: strukturalne dopasowywanie wzorców

Wzorce mogą być prostymi wartościami, lub mogą zawierać bardziej złożoną logikę dopasowywania. Kilka przykładów:

case "a": Dopasowanie przeciwko pojedynczej wartości "a".

case ["a", "b"]: Dopasuj przeciwko kolekcji ["a", "b"].

case ["a", wartość1]: Dopasuj przeciwko kolekcji z dwiema wartościami i umieść drugą wartość w zmiennej przechwytującej value1.

case ["a", *values]: Dopasuj przeciwko kolekcji z co najmniej jedną wartością. Pozostałe wartości, jeśli istnieją, są przechowywane w values. Zauważ, że możesz dołączyć tylko jeden element z gwiazdką na kolekcję (tak jak byłoby to w przypadku argumentów gwiazdkowych w funkcji Pythona).

case ("a"|"b"|"c"): Operator lub (|) może być użyty do umożliwienia obsługi wielu przypadków w pojedynczym bloku przypadków. Tutaj, dopasowujemy przeciwko "a", "b", lub "c".

case ("a"|"b"|"c") jako litera: To samo co powyżej, z tą różnicą, że teraz umieszczamy dopasowany element w zmiennej literał.

case ["a", wartość] if <wyrażenie>: Dopasowuje przechwycenie tylko wtedy, gdy wyrażenie jest prawdziwe. Zmienne przechwytujące mogą być użyte w wyrażeniu. Na przykład, jeśli użylibyśmy if wartość w valid_values, case byłby ważny tylko wtedy, gdy przechwycona wartość faktycznie znajdowałaby się w kolekcji valid_values.

case ["z", _]: Każda kolekcja elementów, która zaczyna się od "z" będzie pasować.

Dopasowywanie do obiektów za pomocą strukturalnego dopasowywania wzorców Pythona

Najbardziej zaawansowaną cechą systemu dopasowywania wzorców strukturalnych Pythona jest możliwość dopasowywania do obiektów o określonych właściwościach. Rozważmy aplikację, w której pracujemy z obiektem o nazwie media_object, który chcemy przekonwertować na plik .jpg i zwrócić z funkcji.

Jak używać strukturalnego dopasowywania wzorców w Pythonie

W każdym z powyższych przypadków szukamy określonego rodzaju obiektu, czasami z określonymi atrybutami. Pierwszy przypadek pasuje do obiektu Image z atrybutem type ustawionym na "jpg". Drugi przypadek pasuje do obiektu typu "png" lub "gif". Trzeci przypadek pasuje do każdego obiektu typu Video, bez względu na jego atrybuty. I ostatni przypadek jest naszym catch-all, jeśli wszystko inne zawiedzie.

Można również wykonać przechwytywanie z dopasowaniem obiektów:

Jak używać strukturalnego dopasowywania wzorców w Pythonie

Efektywne używanie strukturalnego dopasowywania wzorców w Pythonie

Kluczem do dopasowywania wzorców strukturalnych w Pythonie jest pisanie dopasowań, które obejmują przypadki strukturalne, do których próbujesz się dopasować. Proste testy przeciwko stałym są w porządku, ale jeśli to wszystko, co robisz, to proste wyszukiwanie słownikowe może być lepszym rozwiązaniem. Prawdziwą wartością strukturalnego dopasowywania wzorców jest możliwość dopasowywania do wzorca obiektów, a nie tylko do jednego konkretnego obiektu lub nawet ich wyboru.

Źródło:

https://www.infoworld.com/article/3609208/how-to-use-structural-pattern-matching-in-python.html

W celu komercyjnej reprodukcji treści Computerworld należy zakupić licencję. Skontaktuj się z naszym partnerem, YGS Group, pod adresem [email protected]

TOP 200