Гвідо ван Россум (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
", що не забезпечить бажаної продуктивності при обробці дуже великих наборів зіставлень.
Ще немає коментарів