Ответ 1
PEP 572 содержит множество деталей, особенно по первому вопросу. Я постараюсь кратко резюмировать/процитировать некоторые из наиболее важных частей PEP:
Обоснование
Разрешение этой формы присваивания внутри пониманий, таких как списки и лямбда-функции, где традиционные присвоения запрещены. Это также может облегчить интерактивную отладку без необходимости рефакторинга кода.
Синтаксис и семантика
В любом контексте, где могут использоваться произвольные выражения 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)
Рекомендуемые варианты использования
а) Упрощение списка понимания
например:
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)