Гвидо ван Россум предложил включить в Python операторы для сопоставления с образцом
Гвидо ван Россум (Guido van Rossum) представил на рассмотрение сообществом черновик спецификации для реализации в языке Python операторов для сопоставления с образцом (match и case). Следует отметить, что предложения по добавлению операторов сопоставления с образцом уже публиковались в 2001 и 2006 годах (pep-0275, pep-3103), но были отвергнуты в пользу оптимизации конструкции «if … elif … else» для составления цепочек сопоставления.
Новая реализация во многом напоминает оператор «match», предоставляемый в языках Scala, Rust и F#, который выполняет сравнение результата выполнения указанного выражения со списком образцов, перечисленных в блоках на основе оператора «case». В отличие от оператора «switch», доступного в языках Си, Java и JavaScript, выражения на основе «match» предлагают гораздо более широкую функциональность.
def http_error(status): match status: case 400: return "Bad request" case 401|403|404: return "Not allowed" case 418: return "I'm a teapot" case _: return "Something else"
Например, возможна распаковка объектов, кортежей, списков и произвольных последовательностей для привязки переменных на основе имеющихся значений. Допускается определение вложенных шаблонов, использование в шаблоне дополнительных условий «if», применение масок (»[x, y, *rest]»), маппинга связок ключ/значение (например, {«bandwidth»: b, «latency»: l} для извлечения значений «bandwidth» и «latency» и словаря), извлечения подшаблонов (оператор »:=»), использования именованных констант в шаблоне. В классах возможна настройка поведения при сопоставлении при помощи метода »__match__()».
from dataclasses import dataclass @dataclass class Point: x: int y: int def whereis(point): match point: case Point(0, 0): print("Origin") case Point(0, y): print(f"Y={y}") case Point(x, 0): print(f"X={x}") case Point(): print("Somewhere else") case _: print("Not a point") match point: case Point(x, y) if x == y: print(f"Y=X at {x}") case Point(x, y): print(f"Not on the diagonal") RED, GREEN, BLUE = 0, 1, 2 match color: case .RED: print("I see red!") case .GREEN: print("Grass is green") case .BLU E: print("I'm feeling the blues :(")
Для рецензирования подготовлен набор патчей с экспериментальной реализацией предложенной спецификации, но конечный вариант ещё обсуждается. Например, предлагается вместо выражения «case _:» для значения по умолчанию использовать ключевое слово «else:» или «default:», так как »_» в других контекстах применяется как временная переменная. Также вызывают вопросы внутренняя организация, основанная на трансляции новых выражений в байткод, аналогичный используемому для конструкций «if … elif … else», что не обеспечит должной производительности при обработке очень больших наборов сопоставлений.
Источник: http://www.opennet.ru/opennews/art.shtml? num=53248
© OpenNet