
В Python 3.10 имплементирован своего рода оператор switch — что-то вроде него. Оператор switch в других языках, таких как C или Java, выполняет простой матчинг значения переменной и исполняет код в зависимости от этой величины.
Он может использоваться просто, как обычный оператор switch, но способен на гораздо большее.
Возможно, этого было бы достаточно для языка C, но ведь речь о Python, а в Python 3.10 реализована гораздо более мощная и гибкая конструкция, называемая структурным сопоставлением шаблона. Она может использоваться как простой оператор switch, но способна на гораздо большее.
Давайте рассмотрим несложный пример с оператором switch. Ниже приведен сниппет, который осуществляет выбор одного значения. Мы проверим его, запустив в цикле со значениями 1,2,3 и 4.
for thing in [1,2,3,4]: match thing: case 1: print("thing is 1") case 2: print("thing is 2") case 3: print("thing is 3") case _: print("thing is not 1, 2 or 3")
Первое, что бросается в глаза, — это аккуратность синтаксиса. Он начинается с ключевого слова match, за которым следует имя переменной. Затем идет список кейсов, начинающийся с case и сопровождающийся значением, которое сопоставляется. Обратите внимание на использование двоеточий и отступов.
Это не отличается от оператора switch/case в других языках, но в отличие, например, от языка C, после исполнения кода для конкретного кейса проверка переходит к завершению оператора match.
Если совпадения нет, то происходит выполнение кода в случае по умолчанию, обозначенном символом -.
И вот результат.
thing is 1 thing is 2 thing is 3 thing is not 1, 2 or 3
В этом нет ничего удивительного.
Оператор switch — это простой кейс матчинга шаблона, но Python идет немного дальше. Взгляните на этот код:
for thing in [[1,2],[9,10],[1,2,3],[1],[0,0,0,0,0]]: match thing: case [x]: print(f"single value: {x}") case [x,y]: print(f"two values: {x} and {y}") case [x,y,z]: print(f"three values: {x}, {y} and {z}") case _: print("too many values")
Это снова оператор match в цикле, но на этот раз в качестве перечня значений, которые цикл будет итерировать, выступают сами списки — сначала [1,2] затем [9,10] и так далее.
Операторы case пытаются выполнить матчинг этих списков. Первый case соответствует списку с одним элементом, второй — списку с двумя элементами, третий — списку с тремя элементами. Последний case используется по умолчанию.
Но он делает больше, чем это. Он также выполняет биндинг значений, которые сопоставляются с идентификаторами в операторе case. Так, например, первый список — это [1,2], и он соответствует второму случаю [x,y]. Таким образом, в выполняемом коде идентификаторы x и y принимают значения 1 и 2, соответственно. Совсем неплохо, правда?
Итак, результат таков:
two values: 1 and 2 two values: 9 and 10 three values: 1, 2 and 3 single value: 1 too many values
Из нашей первой несложной программы мы знаем, что можно выполнять матчинг значений, а из приведенной выше — матчинг других, более общих шаблонов. Итак, можем ли мы делать матчинг шаблонов, включающих значения? Конечно!
for thing in [[1,2],[9,10],[3,4],[1,2,3],[1],[0,0,0,0,0]]: match thing: case [x]: print(f"single value: {x}") case [1,y]: print(f"two values: 1 and {y}") case [x,10]: print(f"two values: {x} and 10") case [x,y]: print(f"two values: {x} and {y}") case [x,y,z]: print(f"three values: {x}, {y} and {z}") case _: print("too many values")
Например, во втором кейсе мы осуществляем матчинг списка, состоящего из двух элементов, первый из которых имеет значение 1.
Вот результат:
two values: 1 and 2 two values: 9 and 10 two values: 3 and 4 three values: 1, 2 and 3 single value: 1 too many values
Но это еще не все.
Вот программа, которая будет выполнять матчинг списка с любым количеством элементов.
for thing in [[1,2,3,4],['a','b','c'],"this won't be matched"]: match thing: case [*y]: for i in y: print(i) case _: print("unknown")
В первом case индентификатор отмечен звездочкой, и это означает, что к нему можно привязать весь список, который, как мы видим, можно итерировать с помощью цикла.
1 2 3 4 a b c unknown
Это еще не все, но, надеюсь, данная статья дала вам представление о структурном сопоставлении шаблона в Python 3.10.
Более расширенно о дополнительном способе матчинга шаблона я писал здесь.
На сайте Python.org есть полное описание структурного сопоставления шаблона, включая учебное руководство, в PEP 636. Учебник довольно хороший, и я советую вам его прочитать.
В Python 3.10 довольно много новых разработок, помимо структурного матчинга шаблона. О них рассказывается в нескольких статьях, например, см. Джеймс Бриггс Новые возможности в Python 3.10.
Однако имейте в виду, что 3.10 еще только бета-версия, и хотя примеры, которые я показал выше, работают отлично, вам не следует использовать Python 3.10 со всей серьезностью до его официального релиза.
Приглашаем всех заинтересованных на открытое занятие «Знакомство с веб разработкой на Flask». На нем познакомимся с основами веб разработки на Flask, а также научимся создавать и рендерить шаблоны страниц. Попробуем создать Flask приложение, затем создать роуты и в конце обработать различные HTTP методы на Flask. Регистрирация — по ссылке.
