Освойте новую функцию Pattern Matching в Python 3.10. Мы рассмотрим все различные варианты синтаксиса кода.

Сопоставление с образцом, безусловно, самая интересная новая функция в новой версии Python 3.10, и в этом руководстве вы узнаете о ней все!

Его довольно просто понять, но он также содержит множество различных вариантов синтаксиса кода, которые вы можете использовать. Сейчас мы рассмотрим их все. Мы начнем с основного синтаксиса, а затем перейдем ко всем деталям.

1 Basic Syntax

Основной синтаксис довольно прост. Вы используете ключевое слово match и ключевое слово case, а затем можете сопоставлять переменную с разными значениями. Для каждого совпадающего случая вы можете выполнить определенное действие.

В простейшем случае, как здесь, мы сопоставляем простые значения, но вы также можете использовать сложные шаблоны. Вы увидите, что я имею в виду через несколько минут.

Синтаксис:

match subject:
    case <pattern_1>:
        <action_1>
    case <pattern_2>:
        <action_2>
    case _:
        <action_wildcard>

Пример:

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 401 | 403:
            return "Not allowed"
        case 404:
            return "Not found"
          case 418:
            return "I'm a teapot"
        case _:
            return "Something's wrong with the internet"

 

2 Multiple Matches

Мы можем сопоставлять несколько значений в одной строке, используя оператор канала

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 401 | 403 | 404:
              return "Not allowed"

3 No Fall Through

По сравнению с другими языками программирования важно отметить, что здесь мы не пропускаем все случаи. Например, значение 400 здесь выводит только Bad request. В других языках, таких как C++, это пропустит все случаи, а также напечатает все другие операторы, если мы не используем оператор break . Но нам это не нужно здесь, в Python.

def http_error(status):
    match status:
        case 400:
            print("Bad request")
        case 401 | 403 | 404:
              print("Not allowed")

 

4 Wildcard

В качестве подстановочного знака используется одно подчеркивание. Это означает, что если ни один из приведенных выше шаблонов не соответствует, выполняется действие подстановочного знака. Это необязательно, поэтому вы также можете его опустить, и тогда вообще ничего не произойдет, если совпадение не будет найдено.

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case _:
            return "Something's wrong with the internet"

 

5 Unpacking and Variable Binding

Шаблоны могут выглядеть как распаковывающие назначения, и шаблон может использоваться для связывания переменных. В этом примере мы сопоставляем кортеж здесь, и точка данных может быть распакована по ее координатам x и y. Затем мы можем использовать связанную переменную в операторе выполнения.

# point is an (x, y) tuple
match point:
    case (0, 0):
        print("Origin")
    case (0, y):
        print(f"Y={y}")
    case (x, 0):
        print(f"X={x}")
    case (x, y):
        print(f"X={x}, Y={y}")
    case _:
        raise ValueError("Not a point")

6 Patterns and Classes

Если вы используете классы для структурирования своих данных, вы можете использовать в качестве шаблона имя класса, за которым следует список аргументов, соответствующих аргументам конструктора. Этот шаблон имеет возможность записывать атрибуты класса в переменные.

from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int

def location(point):
    match point:
        case Point(x=0, y=0):
            print("Origin is the point's location.")
        case Point(x=0, y=y):
            print(f"Y={y} and the point is on the y-axis.")
        case Point(x=x, y=0):
            print(f"X={x} and the point is on the x-axis.")
        case Point():
            print("The point is located somewhere else on the plane.")
        case _:
            print("Not a point")

 

7 Patterns With Positional Parameters

Мы можем использовать позиционные аргументы, если, например, используем встроенный класс данных, обеспечивающий порядок атрибутов. Тогда все эти шаблоны с позиционными аргументами или аргументами ключевого слова эквивалентны.

Point(1, var)
Point(1, y=var)
Point(x=1, y=var)
Point(y=var, x=1)

 

8 Nested Patterns

Шаблоны могут быть вложены друг в друга. Например, если наши данные представляют собой короткий список точек, их можно сопоставить следующим образом. Здесь мы сопоставляем различные возможные списки.

points = [Point(0, 0), Point(1, 1)]

match points:
    case []:
        print("No points in the list.")
    case [Point(0, 0)]:
        print("The origin is the only point in the list.")
    case [Point(x, y)]:
        print(f"A single point {x}, {y} is in the list.")
    case [Point(0, y1), Point(0, y2)]:
        print(f"Two points on the Y axis at {y1}, {y2} are in the list.")
    case _:
        print("Something else is found in the list.")

 

9 Complex Patterns and the Wildcard

Подстановочный знак можно использовать не только в качестве последнего оператора case, но и в более сложных шаблонах, таких как кортежи. В этом примере переменная состояния соответствует всем кортежам с ошибкой, кодом, а затем любым произвольным номером состояния.

status = ('error', 'Client Error', 100)

match status:
    case ('warning', code, 10):
        print("A warning has been received.")
    case ('error', code, _):
        print(f"An error {code} occurred.")

 

10 Guard

Мы можем добавить предложение if к шаблону, известному как «защита». И если гвардия ложна, совпадение переходит к следующему блоку case.

match point:
    case Point(x, y) if x == y:
        print(f"The point is located on the diagonal Y=X at {x}.")
    case Point(x, y):
        print(f"Point is not on the diagonal.")

 

11 More on Sequences

Шаблоны последовательности также поддерживают подстановочные знаки: эта звездочка в кортеже или списке работает аналогично подстановочным знакам в назначениях распаковки. Таким образом, эти примеры сопоставляют последовательность как минимум из двух элементов, а затем привязывают все оставшиеся элементы к остальным. Имя после звезды также может быть символом подчеркивания, если вам не нужно привязывать остальные элементы.

[x, y, *rest]
(x, y, *rest)
(x, y, *_)

 

12 Mapping Patterns

Подобно последовательностям, мы также можем сопоставлять сопоставления. В этом примере он захватывает значения «пропускной способности» и «задержки» из словаря. Но здесь, в отличие от шаблонов последовательности, лишние ключи игнорируются. Подстановочный знак с двойными звездочками также поддерживается, но двойные звездочки и подчеркивание были бы излишними, поэтому это не разрешено.

{"bandwidth": b, "latency": l}
{"bandwidth": b, **rest}
# {"bandwidth": b, **_}  Not allowed!

 

13 Match with Enum

Конечно, мы также можем сопоставлять перечисления, используя полное имя:

from enum import Enum
class Color(Enum):
    RED = 0
    GREEN = 1
    BLUE = 2

match color:
    case Color.RED:
        print("I see red!")
    case Color.GREEN:
        print("Grass is green")
    case Color.BLUE:
        print("I'm feeling the blues :(")

 

14 Bind Subpatterns with as

И последняя возможность, которую я покажу вам, заключается в том, что подшаблоны могут быть захвачены с помощью ключевого слова as:

В этом примере он связывает x1, y1, x2, y2, как и следовало ожидать без предложения as. И это также связывает p2 со всем вторым элементом.

points = (Point(0, 0), Point(1, 1))

match points:
    case (Point(x1, y1), Point(x2, y2) as p2):
        print(p2)

# --> Point(x=1, y=1)

 

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии