74 votes

Syntaxe ":=" et expressions d'affectation : quoi et pourquoi ?

PEP 572 introduit les expressions d'affectation (familièrement connues sous le nom de Opérateur de morses ), implémentée pour Python 3.8. Il s'agit d'une nouvelle fonctionnalité très importante, car elle permettra cette forme d'affectation dans les compréhensions et les fonctions lambda.

Quelles sont exactement la syntaxe, la sémantique et la spécification grammaticale des expressions d'affectation ?

Pourquoi ce concept nouveau (et apparemment assez radical) est-il introduit, alors qu'une idée similaire dans le domaine de l'éducation est en cours d'élaboration. PEP 379 sur "Ajouter une expression d'affectation" a été rejeté auparavant ?

1 votes

Y a-t-il des questions organiques sur ce sujet qui peuvent être fermées par un lien vers cette question de référence ? Une question qui pourrait autrement être considérée comme "trop large" peut certainement être justifiée lorsqu'elle traite de ce qui est autrement une source de doublons courants.

11 votes

Cela devrait être rouvert. Ce n'est certainement pas "trop large". C'est un sujet très spécifique et une très bonne question de référence.

1 votes

Bien qu'il ne faille pas le prendre trop au pied de la lettre car je suis sûr que Python peut diverger sur certains points, c'est l'une des meilleures caractéristiques de Go et il y a exemples dans toute la documentation de Go

64voto

Chris_Rands Points 15161

PEP 572 contient de nombreux détails, notamment pour la première question. Je vais essayer de résumer/citer de manière concise certaines des parties les plus importantes du PEP :

Justification

Permettre cette forme d'assignation dans les compréhensions, telles que les compréhensions de listes, et les fonctions lambda où les assignations traditionnelles sont interdites. Cela peut également faciliter le débogage interactif sans nécessiter de refactoring du code.

Exemples de cas d'utilisation recommandés

a) Obtenir des 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)

De même, de les docs :

Dans cet exemple, l'expression d'affectation permet d'éviter d'appeler len() deux fois :

if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")

b) Simplifier les compréhensions de 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)]

Syntaxe et sémantique

Dans tout contexte où des expressions Python arbitraires peuvent être utilisées, une expression expression nommée peut apparaître. Celle-ci est de la forme name := exprexpr est toute expression Python valide, et name est un identifiant.

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 déclarations d'affectation ordinaires

En plus d'être une expression plutôt qu'une déclaration, il y a 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 supportent pas :

  • Cibles multiples
x = y = z = 0  # Equivalent: (z := (y := (x := 0)))
  • Les affectations ne sont pas à un seul nom :
# No equivalent
a[i] = x
self.rest = []
  • Emballage/déballage itérable
# 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
  • Annotations de type en ligne :
# Closest equivalent is "p: Optional[int]" as a separate declaration
p: Optional[int] = None
  • L'affectation augmentée n'est pas prise en charge :
total += tax  # Equivalent: (total := total + tax)

0 votes

Je le teste en ce moment et ce n'est pas la seule différence.

0 votes

Il y a toute une liste de différences entre = et := dont un seul est répertorié ici

1 votes

Ce que je veux dire, c'est que cela pourrait être un très bon q&a canonique mais il a besoin d'un sérieux coup de polish.

42voto

Jonathon Reinhart Points 40535

Voici quelques-uns de mes exemples préférés où les expressions d'affectation peuvent rendre le code plus concis et plus facile à lire :

if déclaration

Avant :

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

Après :

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

Infinite while déclaration

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 d'autres bons exemples dans le PEP .

6 votes

Des exemples particulièrement bons : ils montrent un aspect sous lequel C a parfois réussi à être plus clair et plus élégant que Python, j'ai cru qu'ils n'allaient jamais corriger cela

7voto

Charles Clayton Points 7465

Quelques exemples et justifications supplémentaires maintenant que la version 3.8 a été officiellement publiée.

Nommer le résultat d'une expression est une partie importante de la programmation, permettant d'utiliser un nom descriptif à la place d'une expression plus longue, et permettant la réutilisation. Actuellement, cette fonctionnalité n'est disponible que sous forme d'instruction, ce qui la rend indisponible dans les compréhensions de listes et autres contextes d'expression.

Source : Commentaire reddit de LicensedProfessional

Traiter une expression rationnelle

if (match := pattern.search(data)) is not None:
    # Do something with match

Une boucle qui ne peut pas être réécrite trivialement en utilisant 2-arg iter()

while chunk := file.read(8192):
   process(chunk)

Réutiliser une valeur dont le calcul est coûteux

[y := f(x), y**2, y**3]

Partager une sous-expression entre une clause de filtre de compréhension et sa sortie

filtered_data = [y for x in data if (y := f(x)) is not None]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X