Вступление

Впервые предложенный 28 февраля 2018 года в PEP 572 и реализованный Эмили Морхаус, предстоящий выпуск Python 3.8 содержит новую языковую функцию - выражения присваивания. Эта новая функция предоставляет функциональные возможности для присвоения значения переменной в выражении Python, оценки результата, а затем повторного использования переменной в пределах его области видимости. Оператор :=, используемый для определения выражения присваивания, стал в просторечии известен как Оператор Моржа.

В ходе обсуждения этого ПОП оператор стал неофициально называться «оператор моржа». Формальное имя конструкции - «Выражения присваивания» (согласно заголовку PEP), но они также могут называться «Именованные выражения» (например, эталонная реализация CPython использует это имя для внутренних целей).

Основное преимущество, которое предлагают выражения присваивания, - это более сжатый код, снижающий потребность в дополнительных строках кода при присвоении результата выражения переменной перед оценкой.

На высоком уровне выражения присваивания работают, оценивая выражение в правой части оператора := (морж) и присваивая его переменной в левой части оператора. Это дает возможность как оценить логический результат выражения, так и присвоить из него значение для повторного использования в одном простом выражении.

Например. в приведенном ниже примере my_dict.get("name") проверяет my_dict на наличие значения с ключом name. Словарь не имеет значения с этим ключом, поэтому None возвращается и присваивается val с помощью оператора моржа. В контексте условного оператора val затем оценивается и принимается соответствующие меры и, возможно, повторно используется в рамках своей области действия.

Полемика

Как многие люди, вероятно, уже знают, PEP 572, который предлагал эту новую языковую функцию, вызвал значительное количество споров среди разработчиков ядра Python и сообщества в целом.

В конечном итоге это привело к тому, что Гвидо ван Россум, создатель и долгое время BDFL (Доброжелательный диктатор на всю жизнь) Python, отказался от роли BDFL, как указано в его сообщении в списке рассылки Python. под названием Передача власти 12 июля 2018 года.

Синтаксис и допустимое использование

Как описано в PEP 572…

В большинстве случаев, когда можно использовать произвольные выражения Python, может появиться именованное выражение. Он имеет форму NAME: = expr, где expr - любое допустимое выражение Python, кроме кортежа без скобок, а NAME - это идентификатор.

По сути, это означает, что выражение присваивания может использоваться (почти) везде, где допустимое выражение Python могло использоваться до реализации выражений присваивания, за некоторыми исключениями.

Случаи, когда выражение присваивания является допустимым, просто заключаются в том, чтобы избежать какой-либо двусмысленности между двумя теперь разными синтаксисами присвоения значения в Python. Здесь цель состоит в том, чтобы не создавать путаницы в отношении того, какой синтаксис является правильным для данного сценария.

Следующее использование выражений присваивания запрещено (по уважительной причине).

  • На верхнем уровне выражения выражения.
  • На верхнем уровне правой части выражения выражения.
  • Как значение аргумента ключевого слова при вызове функции.
  • В качестве значения по умолчанию верхнего уровня в определении функции.
  • В качестве примечаний к аргументам функции, возвращаемым значениям или присвоениям переменных.
  • Выражения без скобок в лямбда-функциях.

Однако можно обойти эти ограничения, заключив выражение присваивания в круглые скобки, где оно обычно было бы запрещено. Однако это, вероятно, плохая идея. Команда разработчиков ядра Python ввела эти ограничения не зря, чтобы избежать неоднозначного и сложного кода. Как видно из следующих примеров, эти запрещенные использования ничего не добавляют с точки зрения удобочитаемости и во многих случаях делают код очень трудным для понимания.

Примечание. Эти примеры были воспроизведены из раздела исключительные случаи документа PEP572

Еще одно важное правило состоит в том, что выражение присваивания в контексте f-строки необходимо заключать в круглые скобки.

f"Hello, {(name := get_name())}!. Hello, again {name}!"

Объем выражений target

Добавление выражений присваивания в Python не добавляет никакого нового поведения в отношении области целевой переменной выражений присваивания.

Это полезно и позволяет легко подбирать выражения присваивания даже для начинающих разработчиков, поскольку это согласуется с существующим поведением Python.

Соображения производительности

По большей части нет различий в производительности при использовании выражений присваивания. Повышение производительности возможно с помощью выражений присваивания за счет удаления повторяющихся вычислений значений.

Одним из примеров является вычисление значения для выполнения фильтрации в рамках понимания списка.

Примером этого является вычисление степени двойки для диапазона чисел с последующей фильтрацией только круглых чисел в результирующем списке значений. Используя выражение присваивания в понимании списка, чтобы сохранить вычисленное значение pow(x, 2). В приведенном ниже примере время выполнения улучшилось почти на 20% (206 мс).

Заключение

Выражения присваивания и оператор моржа - ценное, освежающее дополнение к Python.

Забота, проявленная командой разработчиков ядра Python в обеспечении простой в освоении функции. Замечательно наличие простого в использовании оператора с небольшим новым синтаксисом.
Если выражения присваивания используются прагматично, они обеспечат улучшенную читаемость и краткость кода. В некоторых случаях повышение производительности также возможно за счет уменьшения необходимости в повторном вычислении значения.

Единственное предостережение - это новая языковая функция, с которой многие разработчики могут быть незнакомы. синтаксис и поведение. В этом случае читаемость кода для таких пользователей может быть снижена.