PEP 572 introduit des expressions d'affectation (familièrement connu sous le nom de Walrus Operator ), implémenté pour Python = 3.8 Cela semble être une nouvelle fonctionnalité vraiment substantielle car elle permettra cette forme d'affectation dans les fonctions de compréhension et lambda.
Quelles sont exactement la syntaxe, la sémantique et la grammaire des expressions d'affectation?
Pourquoi ce nouveau concept (et apparemment assez radical) est-il introduit alors qu'une idée similaire dans PEP 379 sur "Ajouter une expression d'affectation" a été rejetée auparavant?
PEP 572 contient de nombreux détails, en particulier pour la première question. Je vais essayer de résumer/citer de manière concise sans doute certaines des parties les plus importantes du PEP:
Justification
Autoriser cette forme d'affectation dans les compréhensions, telles que les compréhensions de liste et les fonctions lambda où les affectations traditionnelles sont interdites. Cela peut également faciliter le débogage interactif sans avoir besoin de refactorisation de code.
Syntaxe et sémantique
Dans n'importe quel contexte où des expressions arbitraires Python peuvent être utilisées, une expression nommée peut apparaître. Il s'agit de la forme
name := expr
Oùexpr
est une expression Python et nom est un identifiant valide).La valeur d'une telle expression nommée est la même que l'expression incorporée, avec l'effet secondaire supplémentaire que la cible se voit attribuer cette valeur
Différences par rapport aux instructions d'affectation régulières
En plus d'être une expression plutôt qu'une instruction, il existe plusieurs différences mentionnées dans le PEP: les affectations d'expression vont de droite à gauche, ont une priorité différente autour des virgules et ne prennent pas en charge:
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)
Cas d'utilisation recommandés
a) Simplifier la compréhension des listes
par exemple:
stuff = [(lambda y: [y,x/y])(f(x)) for x in range(5)]
peut devenir:
stuff = [[y := f(x), x/y] for x in range(5)]
b) Obtention de valeurs conditionnelles
par exemple (dans Python 3):
command = input("> ")
while command != "quit":
print("You entered:", command)
command = input("> ")
peut devenir:
while (command := input("> ")) != "quit": print("You entered:", command)
Quelques exemples de mes exemples préférés où les expressions d'affectation peuvent rendre le code plus concis et plus facile à lire:
if
instructionAvant:
match = pattern.match(line)
if match:
return match.group(1)
Après:
if match := pattern.match(line):
return match.group(1)
while
Avant:
while True:
data = f.read(1024)
if not data:
break
use(data)
Après:
while data := f.read(1024):
use(data)
Il y a autres bons exemples dans le PEP .