Гвидо ван Россум предложил включить в Python операторы для сопоставления с образцом

29 июня 2020 года

Сопоставление с образцом

Гвидо ван Россум (англ. Guido van Rossum) представил на рассмотрение сообществом черновик спецификации для реализации в языке Python операторов для сопоставления с образцом (match и case). Следует отметить, что предложения по добавлению операторов сопоставления с образцом уже публиковались в 2001 и 2006 годах (pep-0275, pep-3103), но были отвергнуты в пользу оптимизации конструкции «if … elif … else» для составления цепочек сопоставления.

Новая реализация во многом напоминает оператор «match», предоставляемый в языках Scala, Rust и F#, который выполняет сравнение результата выполнения указанного выражения со списком образцов, перечисленных в блоках на основе оператора «case». В отличие от оператора «switch», доступного в языках Си, Java и JavaScript, выражения на основе «match» предлагают гораздо более широкую функциональность. Отмечается, что предложенные операторы позволят улучшить читаемость кода, упростят сопоставление произвольных Python-объектов и отладку, а также повысят надёжность кода благодаря возможности расширенной статической проверки типов.

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», что не обеспечит желаемой производительности при обработке очень больших наборов сопоставлений.

 

ИсточникиПравить

Эта статья содержит материалы из статьи «Гвидо ван Россум предложил включить в Python операторы для сопоставления с образцом», опубликованной OpenNET и распространяющейся на условиях лицензии Creative Commons Attribution (CC BY) — указание автора, источник и лицензию.
 

Комментарии

Викиновости и Wikimedia Foundation не несут ответственности за любые материалы и точки зрения, находящиеся на странице и в разделе комментариев.