Where выражения в Python
Сейчас на python-ideas снова поднялась тема о включении в Python where-выражений. Об этом уже написан PEP–3150, но дискуссия зашла несколько дальше изложенного в нём, и на данный момент, where-выражения стали given-выражениями и выглядят следующим образом:
...
value = a*x*x + b*x + c given:
a = compute_a()
b = compute_b()
c = compute_c()
... # here a, b and c are UNDEFINED
Переменные a, b и c доступны только в выражении, которое предшествует ключевому слову given. Таким образом, этот кусок кода почти эквивалентен следующему:
...
a = compute_a()
b = compute_b()
c = compute_c()
value = a*x*x + b*x + c
... # here a, b and c are DEFINED
За исключением того факта, что в последнем примере мы можем использовать переменные a, b и c и после вычисления value.
В целом, предложение мне нравится:
Повышает читаемость кода. В приведённом примере видно, что является целью вычисления (значение в переменной
value), а что — вспомогательными значениями (a,bиc).Мы можем более смело рефакторить выражения для вычисления вспомогательных значений, не боясь, что они будут использоваться ниже по коду. Таким образом, given-высказывания помогают, “локализовать” контекст вычислений.
Исключается вероятность того, что, в дальнейшем, мы нечаянно (например в результате опечатки) используем одно из вспомогательных значений и вместо
NameErrorполучим какой-то неопределённый и неправильный результат вычисления.
Но, на мой взгляд, у текущего предложения есть недостаток — отсутствие не блочного варианта для given-выражений, что исключает возможность их использования в выражениях для генерации списков и генераторных выражений, например:
mylist = [y for x in collection if y < 10 given y = f(x)]
Весь смысл здесь в том, что значение y вычисляется всего один раз для каждого x из collection в противовес:
mylist = [f(x) for x in collection if f(x) < 10]
Конечно, и сейчас можно “выкрутиться” со следующим решением, но которое, на мой взгляд, всё же проигрывает по читабельности варианту с given:
mylist = [y for y in (f(x) for x in collection) if y < 10]
Guido Van Rossum уже почти за включение where-выражений в Python, но, в любом случае, ещё осталось ждать завершения моратория на изменения в синтаксисе языка.