Гвідо ван Россум запропонував включити в Python оператори для зіставлення із зразком

Alex Alex 29 червня 2020
Гвідо ван Россум запропонував включити в 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" пропонують набагато ширшу функціональність. Зазначається, що запропоновані оператори дозволять поліпшити читаність коду, спростять зіставлення довільних 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=")
           case Point(x, 0):
                print(f"X=")
           case Point():
                print("Somewhere else")
           case _:
                print("Not a point")

 match point:
       case Point(x, y) if x == y:
           print("Y=X at ")
       case Point(x, y):
           print("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 .BLUE:
         print("i'm feeling the blues :(")

Для рецензування підготовлений набір патчів з експериментальної реалізації запропонованої специфікації, але кінцевий варіант ще обговорюється. Наприклад, пропонується замість виразу "case _:" для значення за замовчуванням використовувати ключове слово"else:" або "default:", оскільки "_" в інших контекстах застосовується як тимчасова змінна. Також викликає питання внутрішня організація, заснована на трансляції нових виразів у байткод, аналогічний використанню конструкцій "if ... elif ... else", що не забезпечить бажаної продуктивності при обробці дуже великих наборів зіставлень.

Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.