": =" Синтаксис и выражения присваивания: что и почему? - PullRequest
0 голосов
/ 11 мая 2018

PEP 572 представляет выражения присваивания (общеизвестно как Оператор Моржа ), реализованные для Python 3.8. Это кажется действительно существенной новой функцией, поскольку она позволяет использовать эту форму назначения в пределах функций понимания и лямбда-функций.

Что такое синтаксис, семантика и грамматическая спецификация выражений присваивания?

Почему вводится эта новая (и, казалось бы, довольно радикальная концепция), когда аналогичная идея в PEP 379 о "Добавление выражения присваивания" была ранее отклонена?

Ответы [ 2 ]

0 голосов
/ 22 мая 2019

Несколько моих любимых примеров того, как выражения присваивания могут сделать код более кратким и легким для чтения:

if выписка

До:

match = pattern.match(line)
if match:
    return match.group(1)

После того, как:

if match := pattern.match(line):
    return match.group(1)

Бесконечный while оператор

До:

while True:
    data = f.read(1024)
    if not data:
        break
    use(data)

После того, как:

while data := f.read(1024):
    use(data)

В PEP есть других хороших примеров .

0 голосов
/ 11 мая 2018

PEP 572 содержит множество деталей, особенно для первого вопроса. Я постараюсь кратко резюмировать / процитировать некоторые из наиболее важных частей ПКП:

Обоснование

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

Синтаксис и семантика

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

Значение такого именованного выражения совпадает со встроенным выражением, с дополнительным побочным эффектом того, что целевому объекту присвоено это значение

Отличия от регулярных операторов присваивания

В дополнение к выражению, а не к выражению, в PEP упоминается несколько отличий: назначения выражений идут справа налево, имеют различный приоритет относительно запятых и не поддерживают:

  • Несколько целей
x = y = z = 0  # Equivalent: (z := (y := (x := 0)))
  • Назначения не на одно имя:
# No equivalent
a[i] = x
self.rest = []
  • Повторяемая упаковка / распаковка
# Equivalent needs extra parentheses

loc = x, y  # Use (loc := (x, y))
info = name, phone, *rest  # Use (info := (name, phone, *rest))

# No equivalent

px, py, pz = position
name, phone, email, *other_info = contact
  • Встроенные аннотации типа:
# Closest equivalent is "p: Optional[int]" as a separate declaration
p: Optional[int] = None
  • Расширенное назначение не поддерживается:
total += tax  # Equivalent: (total := total + tax)

Рекомендуемые варианты использования

a) Упрощение списочного понимания

например:

stuff = [(lambda y: [y,x/y])(f(x)) for x in range(5)]

может стать:

stuff = [[y := f(x), x/y] for x in range(5)]

б) Получение условных значений

например (в Python 3):

command = input("> ")
while command != "quit":
    print("You entered:", command)
    command = input("> ")

может стать:

while (command := input("> ")) != "quit":
    print("You entered:", command)
...