Оператор walrus (:=), или оператор присваивания выражения, появился в Python начиная с версии 3.8. Его ввели, чтобы позволить присваивать значение переменной прямо в выражениях (например, в условиях циклов или if), то есть получать и использовать результат функции или вычисления сразу, не повторяя вызов дважды.
Проблема, решаемая walrus — необходимость дублировать вычисления или писать лишние строки кода только для присваивания: до его появления приходилось делать отдельный вызов и затем использовать результат.
Решение: теперь выражение можно сразу присваивать переменной внутри условия, что делает код более лаконичным и, иногда, более читаемым. Важно помнить, что иногда избыточное применение walrus затрудняет понимание кода, особенно для менее опытных коллег.
Пример кода:
while (line := input('Введите строку: ')) != 'exit': print(f'Вы ввели: {line}')
Ключевые особенности:
Можно ли использовать оператор walrus для присваивания значения глобальной переменной?
Да, можно, однако walrus работает в области видимости, где был применён. Нужно помнить о LEGB-правиле и аккуратно использовать переменные вне функций.
В чем разница между x = expr и (x := expr)?
x = expr — самостоятельная инструкция присваивания, тогда как (x := expr) — выражение, возвращающее результат expr и присваивающее его x внутри другого выражения. Во многих случаях второе можно использовать в условиях if, в цикле while или в списковых выражениях.
Может ли walrus использоваться внутри списковых выражений и генераторов?
Да, walrus популярно применяется в comprehension, что особенно удобно для избежания повторных вычислений.
numbers = [int(s) for s in ['1', '2', '3', '4'] if (n := int(s)) > 2] # Здесь n сохраняет результат int(s), экономим вычисления
Разработчик пишет один длинный и запутанный if c несколькими вложенными walrus:
if (a := get_a()) and (b := a.get_b()) and (c := b.do_c()): print(c)
Плюсы:
Минусы:
Осознанное применение для экономии вычислений и читаемости:
while (line := sys.stdin.readline()) != '': process(line)
Плюсы:
Минусы: