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)