6. Expressions
**************

Ce chapitre explique la signification des éléments des expressions en
Python.

**Notes sur la syntaxe :** dans ce chapitre et le suivant, nous
utilisons la notation BNF étendue pour décrire la syntaxe, pas
l'analyse lexicale. Quand une règle de syntaxe est de la forme

   name ::= othername

et qu'aucune sémantique n'est donnée, la sémantique de "name" est la
même que celle de "othername".


6.1. Conversions arithmétiques
==============================

Quand la description d'un opérateur arithmétique ci-dessous utilise la
phrase « les arguments numériques sont convertis vers un type commun
», cela signifie que l'implémentation de l'opérateur fonctionne de la
manière suivante pour les types natifs :

* Si l'un des deux arguments est du type nombre complexe, l'autre est
  converti en nombre complexe ;

* sinon, si l'un des arguments est un nombre à virgule flottante,
  l'autre est converti en nombre à virgule flottante ;

* sinon, les deux doivent être des entiers et aucune conversion n'est
  nécessaire.

Des règles supplémentaires s'appliquent pour certains opérateurs (par
exemple, une chaîne comme opérande de gauche pour l'opérateur "%").
Les extensions doivent définir leurs propres règles de conversion.


6.2. Atomes
===========

Les atomes sont les éléments de base des expressions. Les atomes les
plus simples sont les identifiants et les littéraux. Les expressions
entre parenthèses, crochets ou accolades sont aussi classées
syntaxiquement comme des atomes. La syntaxe pour les atomes est :

   atom      ::= identifier | literal | enclosure
   enclosure ::= parenth_form | list_display | dict_display | set_display
                 | generator_expression | yield_atom


6.2.1. Identifiants (noms)
--------------------------

Un identifiant qui apparaît en tant qu'atome est un nom. Lisez la
section Identifiants et mots-clés pour la définition lexicale et la
section Noms et liaisons pour la documentation sur les noms et les
liaisons afférentes.

Quand un nom est lié à un objet, l'évaluation de l'atome produit cet
objet. Quand le nom n'est pas lié, toute tentative de l'évaluer lève
une exception "NameError".

**Transformation des noms privés :** lorsqu'un identificateur qui
apparaît textuellement dans la définition d'une classe commence par
deux (ou plus) caractères de soulignement et ne se termine pas par
deux (ou plus) caractères de soulignement, il est considéré comme un
*nom privé* de cette classe. Les noms privés sont transformés en une
forme plus longue avant que le code ne soit généré pour eux. La
transformation insère le nom de la classe, avec les soulignés enlevés
et un seul souligné inséré devant le nom. Par exemple,
l'identificateur "__spam" apparaissant dans une classe nommée "Ham"
est transformé en "_Ham__spam". Cette transformation est indépendante
du contexte syntaxique dans lequel l'identificateur est utilisé. Si le
nom transformé est extrêmement long (plus de 255 caractères),
l'implémentation peut le tronquer. Si le nom de la classe est
constitué uniquement de traits de soulignement, aucune transformation
n'est effectuée.


6.2.2. Littéraux
----------------

Python gère les littéraux de chaînes de caractères, de chaînes
d'octets et de plusieurs autres types numériques :

   literal ::= stringliteral | bytesliteral
               | integer | floatnumber | imagnumber

L'évaluation d'un littéral produit un objet du type donné (chaîne de
caractères, chaîne d'octets, entier, nombre à virgule flottante,
nombre complexe) avec la valeur donnée. La valeur peut être approximée
dans le cas des nombres à virgule flottante et des nombres imaginaires
(complexes). Reportez-vous à la section Littéraux pour les détails.

Tous les littéraux sont de types immuables et donc l'identifiant de
l'objet est moins important que sa valeur. Des évaluations multiples
de littéraux avec la même valeur (soit la même occurrence dans le
texte du programme, soit une autre occurrence) résultent dans le même
objet ou un objet différent avec la même valeur.


6.2.3. Formes parenthésées
--------------------------

Une forme parenthésée est une liste d'expressions (cette liste est en
fait optionnelle) placée à l'intérieur de parenthèses :

   parenth_form ::= "(" [starred_expression] ")"

Une liste d'expressions entre parenthèses produit ce que la liste de
ces expressions produirait : si la liste contient au moins une
virgule, elle produit un *n*-uplet (type *n*-uplet) ; sinon, elle
produit l'expression elle-même (qui constitue donc elle-même la liste
d'expressions).

Une paire de parenthèses vide produit un objet *n*-uplet vide. Comme
les n-uplets sont immuables, la même règle que pour les littéraux
s'applique (c'est-à-dire que deux occurrences du *n*-uplet vide
peuvent, ou pas, produire le même objet).

Notez que les *n*-uplets ne sont pas créés par les parenthèses mais
par l'utilisation de la virgule. L'exception est le *n*-uplet vide,
pour lequel les parenthèses *sont requises* (autoriser que « rien » ne
soit pas parenthésé dans les expressions aurait généré des ambigüités
et aurait permis à certaines coquilles de passer inaperçu).


6.2.4. Agencements des listes, ensembles et dictionnaires
---------------------------------------------------------

Pour construire une liste, un ensemble ou un dictionnaire, Python
fournit des syntaxes spéciales dites « agencements » (*displays* en
anglais), chaque agencement comportant deux variantes :

* soit le contenu du conteneur est listé explicitement,

* soit il est calculé à l'aide de la combinaison d'une boucle et
  d'instructions de filtrage, appelée une *compréhension* (dans le
  sens de ce qui sert à définir un concept, par opposition à
  *extension*).

Les compréhensions sont constituées des éléments de syntaxe communs
suivants :

   comprehension ::= assignment_expression comp_for
   comp_for      ::= ["async"] "for" target_list "in" or_test [comp_iter]
   comp_iter     ::= comp_for | comp_if
   comp_if       ::= "if" or_test [comp_iter]

Une compréhension est constituée par une seule expression suivie par
au moins une clause "for" et zéro ou plus clauses "for" ou "if". Dans
ce cas, les éléments du nouveau conteneur sont ceux qui auraient été
produits si l'on avait considéré toutes les clauses "for" ou "if"
comme des blocs, imbriqués de la gauche vers la droite, et évalué
l'expression pour produire un élément à chaque fois que le bloc le
plus imbriqué était atteint.

Cependant, à part l'expression de l'itérable dans la clause "for" la
plus à gauche, la compréhension est exécutée dans une portée séparée,
implicitement imbriquée. Ceci assure que les noms assignés dans la
liste cible ne « fuient » pas en dehors de cette portée.

L'expression de l'itérable dans la clause "for" la plus à gauche est
évaluée directement dans la portée englobante puis passée en tant
qu'argument à la portée implicite imbriquée. Les clauses "for"
suivantes et les filtres conditionnels de la clause "for" la plus à
gauche ne peuvent pas être évalués dans la portée englobante, car ils
peuvent dépendre de valeurs obtenues à partir de l'itérable le plus à
gauche. Par exemple : "[x*y for x in range(10) for y in range(x,
x+10)]".

Pour assurer que le résultat de la compréhension soit un conteneur du
type approprié, les expressions "yield" et "yield from" sont
interdites dans la portée implicite imbriquée.

Depuis Python 3.6, dans une fonction "async def", une clause "async
for" peut être utilisée pour itérer sur un *itérateur asynchrone*. Une
compréhension dans une fonction "async def" consiste alors à avoir,
après cette expression de tête, une clause "for" ou "async for" suivie
par des clauses "for" ou "async for" additionnelles facultatives et,
possiblement, des expressions "await". Si la compréhension contient
des clauses "async for", des expressions "await" ou d'autres
compréhensions asynchrones, elle est appelée *compréhension
asynchrone*. Une compréhension asynchrone peut suspendre l'exécution
de la fonction coroutine dans laquelle elle apparaît. Voir aussi la
**PEP 530**.

Nouveau dans la version 3.6: Les compréhensions asynchrones ont été
introduites.

Modifié dans la version 3.8: "yield" et "yield from" sont interdites
dans la portée implicite imbriquée.

Modifié dans la version 3.11: les compréhensions asynchrones sont
maintenant autorisées dans les compréhensions des fonctions
asynchrones. Les compréhensions englobantes deviennent implicitement
asynchrones.


6.2.5. Agencements de listes
----------------------------

Un agencement de liste est une suite (possiblement vide) d'expressions
à l'intérieur de crochets :

   list_display ::= "[" [starred_list | comprehension] "]"

Un agencement de liste produit un nouvel objet liste, dont le contenu
est spécifié soit par une liste d'expression soit par une
compréhension. Quand une liste d'expressions (dont les éléments sont
séparés par des virgules) est fournie, ces éléments sont évalués de la
gauche vers la droite et placés dans l'objet liste, dans cet ordre.
Quand c'est une compréhension qui est fournie, la liste est construite
à partir des éléments produits par la compréhension.


6.2.6. Agencements d'ensembles
------------------------------

Un agencement d'ensemble (type *set*) est délimité par des accolades
et se distingue de l'agencement d'un dictionnaire par le fait qu'il
n'y a pas de « deux points » ":" pour séparer les clés et les valeurs
:

   set_display ::= "{" (starred_list | comprehension) "}"

Un agencement d'ensemble produit un nouvel objet ensemble mutable, le
contenu étant spécifié soit par une séquence d'expression, soit par
une compréhension. Quand une liste (dont les éléments sont séparés par
des virgules) est fournie, ses éléments sont évalués de la gauche vers
la droite et ajoutés à l'objet ensemble. Quand une compréhension est
fournie, l'ensemble est construit à partir des éléments produits par
la compréhension.

Un ensemble vide ne peut pas être construit par "{}" ; cette écriture
construit un dictionnaire vide.


6.2.7. Agencements de dictionnaires
-----------------------------------

Un agencement de dictionnaire est une série (possiblement vide) de
couples clés-valeurs entourée par des accolades :

   dict_display       ::= "{" [dict_item_list | dict_comprehension] "}"
   dict_item_list     ::= dict_item ("," dict_item)* [","]
   dict_item          ::= expression ":" expression | "**" or_expr
   dict_comprehension ::= expression ":" expression comp_for

Un agencement de dictionnaire produit un nouvel objet dictionnaire.

Si une séquence (dont les éléments sont séparés par des virgules) de
couples clés-valeurs est fournie, les couples sont évalués de la
gauche vers la droite pour définir les entrées du dictionnaire :
chaque objet clé est utilisé comme clé dans le dictionnaire pour
stocker la valeur correspondante. Cela signifie que vous pouvez
spécifier la même clé plusieurs fois dans la liste des couples clés-
valeurs et, dans ce cas, la valeur finalement stockée dans le
dictionnaire est la dernière donnée.

Une double astérisque "**" demande de *dépaqueter le dictionnaire*.
L'opérande doit être un *tableau de correspondances*. Chaque élément
du tableau de correspondances est ajouté au nouveau dictionnaire. Les
valeurs les plus récentes remplacent les valeurs déjà définies par des
couples clés-valeurs antérieurs ou par d'autres dépaquetages de
dictionnaires antérieurs.

Nouveau dans la version 3.5: le dépaquetage peut se faire vers un
agencement de dictionnaire, proposé à l'origine par la **PEP 448**.

Une compréhension de dictionnaire, au contraire des compréhensions de
listes ou d'ensembles, requiert deux expressions séparées par une
virgule et suivies par les clauses usuelles "for" et "if". Quand la
compréhension est exécutée, les éléments clés-valeurs sont insérés
dans le nouveau dictionnaire dans l'ordre dans lequel ils sont
produits.

Les restrictions relatives aux types des clés sont données dans la
section Hiérarchie des types standards (pour résumer, le type de la
clé doit être *hachable*, ce qui exclut tous les objets mutables). Les
collisions entre les clés dupliquées ne sont pas détectées ; la
dernière valeur (celle qui apparaît le plus à droite dans
l'agencement) stockée prévaut pour une clé donnée.

Modifié dans la version 3.8: Avant Python 3.8, dans les compréhensions
de dictionnaires, l'ordre d'évaluation entre les clés et les valeurs
n'était pas bien défini. Dans CPython, la valeur était évaluée avant
la clé. À partir de la version 3.8, la clé est évaluée avant la
valeur, comme proposé par la **PEP 572**.


6.2.8. Expressions génératrices
-------------------------------

Une expression génératrice est une notation concise pour un
générateur, entourée de parenthèses :

   generator_expression ::= "(" expression comp_for ")"

Une expression génératrice produit un nouvel objet générateur. Sa
syntaxe est la même que celle des compréhensions, sauf qu'elle est
entourée de parenthèses au lieu de crochets ou d'accolades.

Les variables utilisées dans une expression génératrice sont évaluées
paresseusement, au moment où la méthode "__next__()" de l'objet
générateur est appelée (de la même manière que pour les générateurs
classiques). Cependant, l'expression de l'itérable dans la clause
"for" la plus à gauche est immédiatement évaluée, de manière à ce
qu'une erreur dans cette partie soit signalée à l'endroit où
l'expression génératrice est définie plutôt qu'à l'endroit où la
première valeur est récupérée. Les clauses "for" suivantes ne peuvent
pas être évaluées dans la portée implicite imbriquée car elles peuvent
dépendre de valeurs obtenues à partir de boucles "for" plus à gauche.
Par exemple, "(x*y for x in range(10) for y in range(x, x+10))".

Les parenthèses peuvent être omises pour les appels qui ne possèdent
qu'un seul argument. Voir la section Appels pour les détails.

Pour éviter d'interférer avec l'opération attendue de l'expression
génératrice elle-même, les expressions "yield" et "yield from" sont
interdites dans les générateurs définis de manière implicite.

Si une expression génératrice contient  une ou des expressions "async
for" ou "await", elle est appelée *expression génératrice asynchrone*.
Une expression génératrice asynchrone produit un nouvel objet
générateur asynchrone qui est un itérateur asynchrone (voir Itérateurs
asynchrones).

Nouveau dans la version 3.6: les expressions génératrices asynchrones
ont été introduites.

Modifié dans la version 3.7: Avant Python 3.7, les expressions
génératrices asynchrones ne pouvaient apparaître que dans les
coroutines "async def". À partir de la version 3.7, toute fonction
peut utiliser des expressions génératrices asynchrones.

Modifié dans la version 3.8: "yield" et "yield from" sont interdites
dans la portée implicite imbriquée.


6.2.9. Expressions "yield"
--------------------------

   yield_atom       ::= "(" yield_expression ")"
   yield_from       ::= "yield" "from" expression
   yield_expression ::= "yield" expression_list | yield_from

Une expression "yield" est utilisée pour définir une *fonction
génératrice* ou une *fonction génératrice asynchrone* et ne peut donc
être utilisée que dans le corps de la définition d'une fonction.
L'utilisation d'une expression "yield" dans le corps d'une fonction
entraîne que cette fonction devient une fonction génératrice et son
utilisation dans le corps d'une fonction "async def" entraine que
cette fonction coroutine devient une fonction génératrice asynchrone.
Par exemple :

   def gen():  # defines a generator function
       yield 123

   async def agen(): # defines an asynchronous generator function
       yield 123

En raison des effets de bords sur la portée contenant, les expressions
"yield" ne sont pas autorisées dans la portée implicite utilisée dans
l'implémentation des compréhensions et des expressions génératrices.

Modifié dans la version 3.8: Les expressions "yield" sont interdites
dans la portée implicite imbriquée utilisée dans l'implémentation des
compréhensions et des expressions génératrices.

Les fonctions génératrices sont décrites plus loin alors que les
fonctions générateurs asynchrones sont décrites séparément dans la
section Fonctions génératrices asynchrones.

Lorsqu'une fonction génératrice est appelée, elle renvoie un itérateur
que l'on appelle générateur. Ce générateur contrôle l'exécution de la
fonction génératrice. L'exécution commence lorsque l'une des méthodes
du générateur est appelée. À ce moment, l'exécution se déroule jusqu'à
la première expression "yield", où elle se suspend, renvoyant la
valeur de "expression_list" à l'appelant du générateur ou "None" si
"expression_list" est omis. Cette suspension conserve tous les états
locaux, y compris les liaisons en cours des variables locales, le
pointeur d'instruction, la pile d'évaluation interne et l'état de tous
les gestionnaires d'exceptions.  Lorsque l'exécution reprend en
appelant l'une des méthodes du générateur, la fonction s'exécute
exactement comme si l'expression "yield" n'avait été qu'un simple
appel externe. La valeur de l'expression "yield" après reprise dépend
de la méthode qui a permis la reprise de l'exécution. Si c'est
"__next__()" qui a été utilisée (généralement *via* un "for" ou la
fonction native "next()") alors le résultat est "None". Sinon, si
c'est "send()" qui a été utilisée, alors le résultat est la valeur
transmise à cette méthode.

Tout ceci rend les fonctions génératrices très similaires aux
coroutines : elles produisent plusieurs objets *via* des expressions
"yield", elles possèdent plus qu'un seul point d'entrée et leur
exécution peut être suspendue. La seule différence est qu'une fonction
génératrice ne peut pas contrôler où l'exécution doit se poursuivre
après une instruction "yield" ; ce contrôle est toujours du ressort de
l'appelant au générateur.

Les expressions "yield" sont autorisées partout dans un bloc "try". Si
l'exécution du générateur ne reprend pas avant qu'il ne soit finalisé
(parce que son compteur de référence est tombé à zéro ou parce qu'il
est nettoyé par le ramasse-miettes), la méthode "close()" du
générateur-itérateur est appelée, ce qui permet l'exécution de toutes
les clauses "finally" en attente.

L'expression passée à "yield from <expr>" doit être un itérateur.
Toutes les valeurs produites par cet itérateur sont directement
passées à l'appelant des méthodes du générateur courant. Toute valeur
passée par "send()" ou toute exception passée par "throw()" est
transmise à l'itérateur sous-jacent s'il possède les méthodes
appropriées. Si ce n'est pas le cas, alors "send()" lève une
"AttributeError" ou une "TypeError", alors que "throw()" ne fait que
propager l'exception immédiatement.

Quand l'itérateur sous-jacent a terminé, l'attribut "value" de
l'instance "StopIteration" qui a été levée devient la valeur produite
par l'expression "yield". Elle peut être définie explicitement quand
vous levez "StopIteration" ou automatiquement que le sous-itérateur
est un générateur (en renvoyant une valeur par le sous-générateur).

Modifié dans la version 3.3: "yield from <expr>" a été ajoutée pour
déléguer le contrôle du flot d'exécution à un sous-itérateur.

Les parenthèses peuvent être omises quand l'expression "yield" est la
seule expression à droite de l'instruction de l'instruction
d'affectation.

Voir aussi:

  **PEP 255** : générateurs simples
     La proposition d'ajouter à Python des générateurs et
     l'instruction "yield".

  **PEP 342** -- Coroutines *via* des générateurs améliorés
     Proposition d'améliorer l'API et la syntaxe des générateurs, de
     manière à pouvoir les utiliser comme de simples coroutines.

  **PEP 380** -- Syntaxe pour déléguer à un sous-générateur
     Proposition d'introduire la syntaxe "yield_from", de manière à
     déléguer facilement l'exécution à un sous-générateur.

  **PEP 525** : Générateurs asynchrones
     La proposition qui a amélioré la **PEP 492** en ajoutant des
     capacités de générateur pour les coroutines.


6.2.9.1. Méthodes des générateurs-itérateurs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Cette sous-section décrit les méthodes des générateurs-itérateurs.
Elles peuvent être utilisées pour contrôler l'exécution des fonctions
génératrices.

Notez que l'appel à une méthode ci-dessous d'un générateur alors que
le générateur est déjà en cours d'exécution lève une exception
"ValueError".

generator.__next__()

   Démarre l'exécution d'une fonction génératrice ou la reprend à la
   dernière expression "yield" exécutée. Quand une fonction
   génératrice est reprise par une méthode "__next__()", l'expression
   "yield" en cours s'évalue toujours à "None". L'exécution continue
   ensuite jusqu'à l'expression "yield" suivante, où le générateur est
   à nouveau suspendu et la valeur de "expression_list" est renvoyée à
   la méthode "__next__()" de l'appelant. Si le générateur termine
   sans donner une autre valeur, une exception "StopIteration" est
   levée.

   Cette méthode est normalement appelée implicitement, par exemple
   par une boucle "for" ou par la fonction native "next()".

generator.send(value)

   Reprend l'exécution et « envoie » une valeur à la fonction
   génératrice. L'argument *value* devient le résultat de l'expression
   "yield" courante. La méthode "send()" renvoie la valeur suivante
   produite par le générateur ou lève "StopIteration" si le générateur
   termine sans produire de nouvelle valeur. Quand "send()" est
   utilisée pour démarrer le générateur, elle doit avoir "None" comme
   argument, car il n'y a aucune expression "yield" qui peut recevoir
   la valeur.

generator.throw(value)
generator.throw(type[, value[, traceback]])

   Lève une exception à l'endroit où le générateur est en pause et
   renvoie la valeur suivante produite par la fonction génératrice. Si
   le générateur termine sans produire de nouvelle valeur, une
   exception "StopIteration" est levée. Si la fonction génératrice ne
   gère pas l'exception passée ou lève une autre exception, alors
   cette exception est propagée vers l'appelant.

   Dans son utilisation typique, elle est appelée avec une seule
   instance d'exception, de façon similaire à l'utilisation du mot-clé
   "raise".

   Cependant, pour assurer la rétrocompatibilité, la deuxième
   signature est prise en charge, suivant une convention des anciennes
   versions de Python. L'argument *type* doit être une classe
   d'exception et *value* doit être une instance d'exception. Si
   *value* n'est pas fournie, le constructeur de *type* est appelé
   pour obtenir une instance. Si *traceback* est fournie, elle est
   liée sur l'exception, sinon tout attribut "__traceback__" existant
   stocké dans *value* est possiblement effacé.

generator.close()

   Lève une "GeneratorExit" à l'endroit où la fonction génératrice a
   été mise en pause. Si la fonction génératrice termine, est déjà
   fermée ou lève "GeneratorExit" (parce qu'elle ne gère pas
   l'exception), *close* revient vers l'appelant. Si le générateur
   produit une valeur, une  "RuntimeError" est levée. Si le générateur
   lève une autre exception, elle est propagée à l'appelant. La
   méthode "close()" ne fait rien si le générateur a déjà terminé en
   raison d'une exception ou d'une fin normale.


6.2.9.2. Exemples
~~~~~~~~~~~~~~~~~

Voici un exemple simple qui montre le comportement des générateurs et
des fonctions génératrices :

   >>> def echo(value=None):
   ...     print("Execution starts when 'next()' is called for the first time.")
   ...     try:
   ...         while True:
   ...             try:
   ...                 value = (yield value)
   ...             except Exception as e:
   ...                 value = e
   ...     finally:
   ...         print("Don't forget to clean up when 'close()' is called.")
   ...
   >>> generator = echo(1)
   >>> print(next(generator))
   Execution starts when 'next()' is called for the first time.
   1
   >>> print(next(generator))
   None
   >>> print(generator.send(2))
   2
   >>> generator.throw(TypeError, "spam")
   TypeError('spam',)
   >>> generator.close()
   Don't forget to clean up when 'close()' is called.

Pour des exemples d'utilisation de "yield from", lisez la PEP 380:
Syntax for Delegating to a Subgenerator dans « Les nouveautés de
Python ».


6.2.9.3. Fonctions génératrices asynchrones
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

La présence d'une expression *yield* dans une fonction ou une méthode
définie en utilisant "async def" transforme cette fonction en fonction
*générateur asynchrone*.

Quand une fonction génératrice asynchrone est appelée, elle renvoie un
itérateur asynchrone, autrement appelé objet générateur asynchrone.
Cet objet contrôle l'exécution de la fonction génératrice. Un objet
générateur asynchrone est typiquement utilisé dans une instruction
"async for" à l'intérieur d'une fonction coroutine de la même manière
qu'un objet générateur serait utilisé dans une instruction "for".

L'appel d'une méthode du générateur asynchrone renvoie un objet
*awaitable* et l'exécution commence au moment où l'on atteint une
instruction "await" le concernant. À ce moment, l'exécution se déroule
jusqu'à la première expression "yield", où elle est suspendue et
renvoie la valeur de "expression_list" à la coroutine en attente.
Comme pour un générateur, la suspension signifie que tous les états
locaux sont conservés, y compris les liaisons des variables locales,
le pointeur d'instruction, la pile d'évaluation interne et l'état de
tous les gestionnaires d'exceptions. Lorsque l'exécution reprend parce
que l'appelant a atteint une instruction "await" sur l'objet suivant
retourné par les méthodes du générateur asynchrone, la fonction
s'exécute exactement comme si l'expression "yield" n'avait été qu'un
simple appel externe. La valeur de l'expression "yield" au moment de
la reprise dépend de la méthode qui a relancé l'exécution. Si c'est
"__anext__()" qui a été utilisée, alors le résultat est "None". Sinon,
si c'est "asend()" qui a été utilisée, alors le résultat est la valeur
transmise à cette méthode.

Si un générateur asynchrone se termine précipitamment en raison d'un
"break", de l'annulation de la tâche de l'appelant ou d'une exception,
le code de nettoyage du générateur asynchrone est exécuté et lève
possiblement des exceptions, accède à des variables de contexte dans
un contexte inattendu — peut-être parce que la tâche de laquelle il
dépend est finie, ou pendant la fermeture de la boucle d'événements
quand le point d'entrée du ramasse-miettes a déjà été appelé. Afin
d'éviter cette situation, l'appelant doit explicitement fermer le
générateur asynchrone en appelant la méthode "aclose()" pour «
finaliser » le générateur et le détacher de la boucle d'événements.

Dans une fonction génératrice asynchrone, les expressions "yield" sont
autorisées n'importe où dans une construction "try". Cependant, si
l'exécution d'un générateur asynchrone n'a pas repris avant que le
générateur ne soit finalisé (parce que son compteur de référence a
atteint zéro ou parce qu'il est nettoyé par le ramasse-miettes), alors
une expression "yield" dans une construction "try" pourrait ne pas
atteindre la clause "finally" en attente. Dans ce cas, c'est la
responsabilité de la boucle d'événements ou du programmateur exécutant
le générateur asynchrone d'appeler la méthode "aclose()" du générateur
asynchrone et d'exécuter l'objet coroutine résultant, permettant ainsi
à toute clause "finally" en attente d'être exécutée.

Pour effectuer correctement la finalisation, une boucle d'événements
doit définir une fonction *finalizer* qui prend un générateur-
itérateur asynchrone, appelle sans doute "aclose()" et exécute la
coroutine. Ce *finalizer* peut s'enregistrer en appelant
"sys.set_asyncgen_hooks()". Lors de la première itération, un
générateur-itérateur asynchrone stocke le *finalizer* enregistré à
appeler lors de la finalisation. Pour un exemple de référence relatif
à une méthode de *finalizer*, regardez l'implémentation de
"asyncio.Loop.shutdown_asyncgens" dans Lib/asyncio/base_events.py.

L'expression "yield from <expr>" produit une erreur de syntaxe quand
elle est utilisée dans une fonction génératrice asynchrone.


6.2.9.4. Méthodes des générateurs-itérateurs asynchrones
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Cette sous-section décrit les méthodes des générateurs-itérateurs
asynchrones. Elles sont utilisées pour contrôler l’exécution des
fonctions génératrices.

coroutine agen.__anext__()

   Renvoie un *awaitable* qui, quand il a la main, démarre l'exécution
   du générateur asynchrone ou reprend son exécution à l'endroit de la
   dernière expression "yield" exécutée. Quand une fonction
   génératrice asynchrone est reprise par une méthode "__anext__()",
   l’expression "yield" en cours s’évalue toujours à "None" dans le
   *awaitable* renvoyé, et elle continue son exécution jusqu’à
   l’expression "yield" suivante. La valeur de "expression_list" de
   l'expression "yield" est la valeur de l'exception "StopIteration"
   levée par la coroutine qui termine. Si le générateur asynchrone
   termine sans produire d'autre valeur, le *awaitable* lève une
   exception "StopAsyncIteration" qui signale que l'itération
   asynchrone est terminée.

   Cette méthode est normalement appelée implicitement par une boucle
   "async for".

coroutine agen.asend(value)

   Renvoie un *awaitable* qui, lorsqu'il a la main, reprend
   l'exécution du générateur asynchrone. Comme pour la méthode
   "send()" d'un générateur, elle « envoie » une valeur *value* à la
   fonction génératrice asynchrone et cet argument devient le résultat
   de l'expression "yield" courante. Le *awaitable* renvoyé par la
   méthode "asend()" renvoie la valeur suivante produite par le
   générateur comme valeur de l'exception "StopIteration" levée ou
   lève "StopAsyncIteration" si le générateur asynchrone termine sans
   produire de nouvelle valeur. Quand "asend()" est appelée pour
   démarrer le générateur asynchrone, l'argument doit être "None" car
   il n'y a pas d'expression "yield" pour recevoir la valeur.

coroutine agen.athrow(value)
coroutine agen.athrow(type[, value[, traceback]])

   Renvoie un *awaitable* qui lève une exception du type "type" à
   l'endroit où le générateur asynchrone a été mis en pause et renvoie
   la valeur suivante produite par la fonction génératrice comme
   valeur de l'exception "StopIteration" qui a été levée. Si le
   générateur asynchrone termine sans produire de nouvelle valeur, une
   exception "StopAsyncIteration" est levée par le *awaitable*. Si la
   fonction génératrice ne traite pas l'exception reçue ou lève une
   autre exception alors, quand le *awaitable* est lancé, cette
   exception est propagée vers l'appelant du *awaitable*.

coroutine agen.aclose()

   Renvoie un *awaitable* qui, quand il s'exécute, lève une exception
   "GeneratorExit" dans la fonction génératrice asynchrone à l'endroit
   où le générateur était en pause. Si la fonction génératrice
   asynchrone termine normalement, est déjà fermée ou lève
   "GeneratorExit" (parce qu'elle ne gère pas l'exception), alors le
   *awaitable* renvoyé lève une exception "StopIteration". Tout
   nouveau *awaitable* produit par un appel postérieur au générateur
   asynchrone lève une exception "StopAsyncIteration". Si le
   générateur asynchrone produit une valeur, une "RuntimeError" est
   levée par le *awaitable*. Si le générateur asynchrone lève une
   autre exception, elle est propagée à l'appelant du *awaitable*. Si
   le générateur asynchrone a déjà terminé (soit par une exception,
   soit normalement), alors tout nouvel appel à "aclose()" renvoie un
   *awaitable* qui ne fait rien.


6.3. Primaires
==============

Les primaires (*primary* dans la grammaire formelle ci-dessous)
représentent les opérations qui se lient au plus proche dans le
langage. Leur syntaxe est :

   primary ::= atom | attributeref | subscription | slicing | call


6.3.1. Références à des attributs
---------------------------------

Une référence à un attribut (*attributeref* dans la grammaire formelle
ci-dessous) est une primaire suivie par un point et un nom :

   attributeref ::= primary "." identifier

The primary must evaluate to an object of a type that supports
attribute references, which most objects do.  This object is then
asked to produce the attribute whose name is the identifier. The type
and value produced is determined by the object.  Multiple evaluations
of the same attribute reference may yield different objects.

This production can be customized by overriding the
"__getattribute__()" method or the "__getattr__()" method.  The
"__getattribute__()" method is called first and either returns a value
or raises "AttributeError" if the attribute is not available.

If an "AttributeError" is raised and the object has a "__getattr__()"
method, that method is called as a fallback.


6.3.2. sélection (ou indiçage)
------------------------------

L'indiçage d'une instance de classe conteneur sélectionne généralement
un élément du conteneur. L'indiçage d'une *classe générique* renvoie
généralement un objet GenericAlias.

   subscription ::= primary "[" expression_list "]"

Lorsqu'on accède à l'indice d'un objet, l'interpréteur évalue la
primaire et la liste d'expressions.

L'évaluation de la primaire doit produire un objet qui gère
l'indiçage. Un objet est susceptible de gérer l'indiçage s'il définit
la ou les deux méthodes "__getitem__()" et "__class_getitem__()".
Quand on spécifie un indice du primaire, le résultat de l'évaluation
de la liste d'expression est passé à l'une de ces méthodes. Pour plus
de détails sur le choix de "__class_getitem__" ou "__getitem__" pour
l'appel, lisez __class_getitem__ contre __getitem__.

Si la liste d'expressions contient au moins une virgule, elle est
considérée comme un "n-uplet" contenant les éléments de la liste
d'expressions. Sinon, la liste d'expressions est évaluée à la valeur
du seul membre de la liste.

Pour les objets natifs, deux types d'objets gèrent la sélection *via*
"__getitem__()" :

1. Si la primaire est un *tableau de correspondances*, la liste
   d'expressions (*expression_list* dans la grammaire formelle ci-
   dessous) doit pouvoir être évaluée comme un objet dont la valeur
   est une des clés du tableau de correspondances et la sélection
   désigne la valeur qui correspond à cette clé. Un exemple de classe
   implémentant le concept de tableau de correspondances est la classe
   "dict".

2. Si la primaire est une *séquence*, la liste d'expressions
   (*expression_list* dans la grammaire) doit pouvoir être évaluée
   comme un "entier" ou une "tranche" (comme expliqué dans la section
   suivante). Des exemples de classes natives implémentant le concept
   de séquence sont les "chaînes", "listes" et les "n-uplets".

The formal syntax makes no special provision for negative indices in
*sequences*. However, built-in sequences all provide a "__getitem__()"
method that interprets negative indices by adding the length of the
sequence to the index so that, for example, "x[-1]" selects the last
item of "x". The resulting value must be a nonnegative integer less
than the number of items in the sequence, and the subscription selects
the item whose index is that value (counting from zero). Since the
support for negative indices and slicing occurs in the object's
"__getitem__()" method, subclasses overriding this method will need to
explicitly add that support.

Une "chaîne" est une espèce particulière de séquence dont les éléments
sont des *caractères*. Un caractère n'est pas un type en tant que tel,
c'est une chaîne de longueur un.


6.3.3. Tranches
---------------

Une tranche (*slicing* dans la grammaire formelle ci-dessous)
sélectionne un intervalle d'éléments d'un objet séquence (par exemple
une chaîne, un n-uplet ou une liste, respectivement les types
*string*, *tuple* et *list*). Les tranches peuvent être utilisées
comme des expressions ou des cibles dans les affectations ou les
instructions "del". La syntaxe est la suivante :

   slicing      ::= primary "[" slice_list "]"
   slice_list   ::= slice_item ("," slice_item)* [","]
   slice_item   ::= expression | proper_slice
   proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]
   lower_bound  ::= expression
   upper_bound  ::= expression
   stride       ::= expression

Il existe une ambigüité dans la syntaxe formelle ci-dessus : tout ce
qui ressemble à une liste d'expressions (*expression_list* vue avant)
ressemble aussi à une liste de tranches (*slice_list* dans la
grammaire ci-dessus). En conséquence, toute sélection (*subscription*
dans la grammaire) peut être interprétée comme une tranche. Plutôt que
de compliquer encore la syntaxe, l'ambigüité est levée en disant que,
dans ce cas, l'interprétation en tant que sélection (*subscription*)
est prioritaire sur l'interprétation en tant que tranche (c'est le cas
si la liste de tranches (*slice_list*) ne contient aucune tranche en
tant que telle).

The semantics for a slicing are as follows.  The primary is indexed
(using the same "__getitem__()" method as normal subscription) with a
key that is constructed from the slice list, as follows.  If the slice
list contains at least one comma, the key is a tuple containing the
conversion of the slice items; otherwise, the conversion of the lone
slice item is the key.  The conversion of a slice item that is an
expression is that expression.  The conversion of a proper slice is a
slice object (see section Hiérarchie des types standards) whose
"start", "stop" and "step" attributes are the values of the
expressions given as lower bound, upper bound and stride,
respectively, substituting "None" for missing expressions.


6.3.4. Appels
-------------

Un appel (*call* dans la grammaire ci-dessous) appelle un objet
appelable (par exemple, une *fonction*) avec, possiblement, une liste
d'*arguments* :

   call                 ::= primary "(" [argument_list [","] | comprehension] ")"
   argument_list        ::= positional_arguments ["," starred_and_keywords]
                       ["," keywords_arguments]
                     | starred_and_keywords ["," keywords_arguments]
                     | keywords_arguments
   positional_arguments ::= positional_item ("," positional_item)*
   positional_item      ::= assignment_expression | "*" expression
   starred_and_keywords ::= ("*" expression | keyword_item)
                            ("," "*" expression | "," keyword_item)*
   keywords_arguments   ::= (keyword_item | "**" expression)
                          ("," keyword_item | "," "**" expression)*
   keyword_item         ::= identifier "=" expression

Une virgule finale (optionnelle) peut être présente, après les
arguments positionnels et nommés, mais elle n'affecte pas la
sémantique.

The primary must evaluate to a callable object (user-defined
functions, built-in functions, methods of built-in objects, class
objects, methods of class instances, and all objects having a
"__call__()" method are callable).  All argument expressions are
evaluated before the call is attempted.  Please refer to section
Définition de fonctions for the syntax of formal *parameter* lists.

Si des arguments par mots-clés sont présents, ils sont d'abord
convertis en arguments positionnels, comme suit. Pour commencer, une
liste de *slots* vides est créée pour les paramètres formels. S'il y a
N arguments positionnels, ils sont placés dans les N premiers *slots*.
Ensuite, pour chaque argument nommé, l'identifiant est utilisé pour
déterminer le *slot* correspondant (si l'identifiant est le même que
le nom du premier paramètre formel, le premier *slot* est utilisé, et
ainsi de suite). Si le *slot* est déjà rempli, une exception
"TypeError" est levée. Sinon, l'argument est placé dans le *slot*, ce
qui le remplit (même si l'expression est "None", cela remplit le
*slot*). Quand tous les arguments ont été traités, les *slots* qui
sont toujours vides sont remplis avec la valeur par défaut
correspondante dans la définition de la fonction (les valeurs par
défaut sont calculées, une seule fois, lorsque la fonction est définie
; ainsi, un objet mutable tel qu'une liste ou un dictionnaire utilisé
en tant valeur par défaut sera partagé entre tous les appels qui ne
spécifient pas de valeur d argument pour ce *slot* ; on évite
généralement de faire ça). S'il reste des *slots* pour lesquels aucune
valeur par défaut n'est définie, une exception "TypeError" est levée.
Sinon, la liste des *slots* remplie est utilisée en tant que liste des
arguments pour l'appel.

**Particularité de l'implémentation CPython :** Une implémentation
peut fournir des fonctions natives dont les paramètres positionnels
n'ont pas de nom, même s'ils sont « nommés » pour les besoins de la
documentation. Ils ne peuvent donc pas être fournis comme arguments
nommés. En CPython, les fonctions implémentées en C qui utilisent
"PyArg_ParseTuple()" pour analyser leurs arguments en font partie.

S'il y a plus d'arguments positionnels que de *slots* de paramètres
formels, une exception "TypeError" est levée, à moins qu'un paramètre
formel n'utilise la syntaxe "*identifier" ; dans ce cas, le paramètre
formel reçoit un *n*-uplet contenant les arguments positionnels en
supplément (ou un *n*-uplet vide s'il n'y avait pas d'argument
positionnel en trop).

Si un argument nommé ne correspond à aucun nom de paramètre formel,
une exception "TypeError" est levée, à moins qu'un paramètre formel
n'utilise la syntaxe "**identifier" ; dans ce cas, le paramètre formel
reçoit un dictionnaire contenant les arguments nommés en trop (en
utilisant les mots-clés comme clés et les arguments comme valeurs pour
ce dictionnaire), ou un (nouveau) dictionnaire vide s'il n'y a pas
d'argument nommé en trop.

Si la syntaxe "*expression" apparaît dans l'appel de la fonction,
"expression" doit pouvoir s'évaluer à un *itérable*. Les éléments de
ces itérables sont traités comme s'ils étaient des arguments
positionnels supplémentaires. Pour l'appel "f(x1, x2, *y, x3, x4)", si
*y* s'évalue comme une séquence *y1* … *yM*, c'est équivalent à un
appel avec M+4 arguments positionnels *x1*, *x2*, *y1* … *yM*, *x3*,
*x4*.

Une conséquence est que bien que la syntaxe "*expression" puisse
apparaître *après* les arguments par nommés explicites, ils sont
traités *avant* les arguments nommés (et avant tout argument
"**expression" -- voir ci-dessous). Ainsi :

   >>> def f(a, b):
   ...     print(a, b)
   ...
   >>> f(b=1, *(2,))
   2 1
   >>> f(a=1, *(2,))
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: f() got multiple values for keyword argument 'a'
   >>> f(1, *(2,))
   1 2

Il est inhabituel que les syntaxes d'arguments par mots-clés et
"*expression" soient utilisés simultanément dans un même appel, ce qui
fait que la confusion reste rare.

Si la syntaxe "**expression" apparaît dans un appel de fonction,
"expression" doit pouvoir s'évaluer comme un *tableau de
correspondances*, dont le contenu est traité comme des arguments par
mots-clés supplémentaires. Si un paramètre correspondant à une clé a
déjà été fourni (en tant qu'argument nommé explicite, en provenance
d'un autre dépaquetage), une exception "TypeError" est levée.

Lorsque "**expression" est utilisée, chaque clé de ce tableau de
correspondances doit être une chaîne. Chaque valeur du tableau est
affectée au premier paramètre formel éligible à l'affectation par mot-
clé dont le nom est égal à la clé. Une clé n'a pas besoin d'être un
identifiant Python (par exemple, ""max-temp °F"" est acceptable, bien
qu'elle ne corresponde à aucun paramètre formel qui pourrait être
déclaré). S'il n'y a pas de correspondance avec un paramètre formel,
la paire clé-valeur est collectée par le paramètre "**", s'il y en a
un. S'il n'y a pas de paramètre "**", une exception "TypeError" est
levée.

Les paramètres formels qui utilisent la syntaxe "*identifier" ou
"**identifier" ne peuvent pas être utilisés comme arguments
positionnels ou comme noms d'arguments par mots-clés.

Modifié dans la version 3.5: Les appels de fonction acceptent
n'importe quel nombre de dépaquetages par "*" ou "**". Des arguments
positionnels peuvent suivre les dépaquetages d'itérables ("*") et les
arguments par mots-clés peuvent suivre les dépaquetages de
dictionnaires ("**"). Proposé pour la première fois par la **PEP
448**.

Un appel renvoie toujours une valeur, possiblement "None", à moins
qu'il ne lève une exception. La façon dont celle valeur est calculée
dépend du type de l'objet appelable.

Si c'est

une fonction définie par l'utilisateur :
   le bloc de code de la fonction est exécuté, il reçoit la liste des
   arguments. La première chose que le bloc de code fait est de lier
   les paramètres formels aux arguments ; ceci est décrit dans la
   section Définition de fonctions. Quand le bloc de code exécute
   l'instruction "return", cela spécifie la valeur de retour de
   l'appel de la fonction.

une fonction ou une méthode native :
   le résultat dépend de l'interpréteur ; lisez Fonctions natives pour
   une description des fonctions et méthodes natives.

un objet classe :
   une nouvelle instance de cette classe est renvoyée.

une méthode d'instance de classe :
   la fonction correspondante définie par l'utilisateur est appelée,
   avec la liste d'arguments qui est plus grande d'un élément que la
   liste des arguments de l'appel : l'instance est placée en tête des
   arguments.

une instance de classe :
   The class must define a "__call__()" method; the effect is then the
   same as if that method was called.


6.4. Expression "await"
=======================

Suspend l'exécution de la *coroutine* sur un objet *awaitable*. Ne
peut être utilisée qu'à l'intérieur d'une *coroutine function*.

   await_expr ::= "await" primary

Nouveau dans la version 3.5.


6.5. L'opérateur puissance
==========================

L'opérateur puissance est plus prioritaire que les opérateurs unaires
sur sa gauche ; il est moins prioritaire que les opérateurs unaires
sur sa droite. La syntaxe est :

   power ::= (await_expr | primary) ["**" u_expr]

Ainsi, dans une séquence sans parenthèse de puissance et d'opérateurs
unaires, les opérateurs sont évalués de droite à gauche (ceci ne
contraint pas l'ordre d'évaluation des opérandes) : "-1**2" donne
"-1".

L'opérateur puissance possède la même sémantique que la fonction
native "pow()" lorsqu'elle est appelée avec deux arguments : il
produit son argument de gauche élevé à la puissance de son argument de
droite. Les arguments numériques sont d'abord convertis vers un type
commun et le résultat est de ce type.

Pour les opérandes entiers, le résultat est du même type à moins que
le deuxième argument ne soit négatif ; dans ce cas, tous les arguments
sont convertis en nombres à virgule flottante et le résultat est un
nombre à virgule flottante. Par exemple, "10**2" renvoie "100" mais
"10**-2" renvoie "0.01".

Élever "0.0" à une puissance négative entraîne une
"ZeroDivisionError". Élever un nombre négatif à une puissance
fractionnaire renvoie un nombre "complexe" (dans les versions
antérieures, cela levait une "ValueError").

This operation can be customized using the special "__pow__()" method.


6.6. Arithmétique unaire et opérations sur les bits
===================================================

Toute l'arithmétique unaire et les opérations sur les bits ont la même
priorité :

   u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr

The unary "-" (minus) operator yields the negation of its numeric
argument; the operation can be overridden with the "__neg__()" special
method.

The unary "+" (plus) operator yields its numeric argument unchanged;
the operation can be overridden with the "__pos__()" special method.

The unary "~" (invert) operator yields the bitwise inversion of its
integer argument.  The bitwise inversion of "x" is defined as
"-(x+1)".  It only applies to integral numbers or to custom objects
that override the "__invert__()" special method.

Dans ces trois cas, si l'argument n'est pas du bon type, une exception
"TypeError" est levée.


6.7. Opérations arithmétiques binaires
======================================

Les opérations arithmétiques binaires suivent les conventions pour les
priorités. Notez que certaines de ces opérations s'appliquent aussi à
des types non numériques. À part l'opérateur puissance, il n'y a que
deux niveaux, le premier pour les opérateurs multiplicatifs et le
second pour les opérateurs additifs :

   m_expr ::= u_expr | m_expr "*" u_expr | m_expr "@" m_expr |
              m_expr "//" u_expr | m_expr "/" u_expr |
              m_expr "%" u_expr
   a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr

L'opérateur "*" (multiplication) produit le produit de ses arguments.
Les deux arguments doivent être des nombres ou alors le premier
argument doit être un entier et l'autre doit être une séquence. Dans
le premier cas, les nombres sont convertis dans un type commun puis
sont multipliés entre eux. Dans le dernier cas, la séquence est
répétée ; une répétition négative produit une séquence vide.

This operation can be customized using the special "__mul__()" and
"__rmul__()" methods.

L'opérateur "@" (prononcé *at* en anglais) a vocation à multiplier des
matrices. Aucun type Python natif n'implémente cet opérateur.

Nouveau dans la version 3.5.

Les opérateurs "/" (division) et "//" (division entière ou *floor
division* en anglais) produisent le quotient de leurs arguments. Les
arguments numériques sont d'abord convertis vers un type commun. La
division d'entiers produit un nombre à virgule flottante alors que la
division entière d'entiers produit un entier ; le résultat est celui
de la division mathématique suivie de la fonction "floor" appliquée au
résultat. Une division par zéro lève une exception
"ZeroDivisionError".

This operation can be customized using the special "__truediv__()" and
"__floordiv__()" methods.

L'opérateur "%" (modulo) produit le reste de la division entière du
premier argument par le second. Les arguments numériques sont d'abord
convertis vers un type commun. Un zéro en second argument lève une
exception "ZeroDivisionError". Les arguments peuvent être des nombres
à virgule flottante, par exemple "3.14%0.7" vaut "0.34" (puisque
"3.14" égale "4*0.7+0.34"). L'opérateur modulo produit toujours un
résultat du même signe que le second opérande (ou zéro) ; la valeur
absolue du résultat est strictement inférieure à la valeur absolue du
second opérande [1].

Les opérateurs division entière et modulo sont liés par la relation
suivante : "x == (x//y)*y + (x%y)". La division entière et le module
sont aussi liés à la fonction native  "divmod()" : "divmod(x, y) ==
(x//y, x%y)" [2].

En plus de calculer le modulo sur les nombres, l'opérateur "%" est
aussi surchargé par les objets chaînes de caractères pour effectuer le
formatage de chaîne « à l'ancienne ». La syntaxe pour le formatage de
chaînes est décrit dans la référence de la bibliothèque Python, dans
la section  Formatage de chaines à la printf.

The *modulo* operation can be customized using the special "__mod__()"
method.

L'opérateur de division entière, l'opérateur modulo et la fonction
"divmod()" ne sont pas définis pour les nombres complexes. À la place,
vous pouvez, si cela a du sens pour ce que vous voulez faire, les
convertir vers des nombres à virgule flottante en utilisant la
fonction "abs()".

L'opérateur "+" (addition) produit la somme de ses arguments. Les
arguments doivent être tous les deux des nombres ou des séquences du
même type. Dans le premier cas, les nombres sont convertis vers un
type commun puis sont additionnés entre eux. Dans le dernier cas, les
séquences sont concaténées.

This operation can be customized using the special "__add__()" and
"__radd__()" methods.

L'opérateur "-" (soustraction) produit la différence entre ses
arguments. Les arguments numériques sont d'abord convertis vers un
type commun.

This operation can be customized using the special "__sub__()" method.


6.8. Opérations de décalage
===========================

Les opérations de décalage sont moins prioritaires que les opérations
arithmétiques :

   shift_expr ::= a_expr | shift_expr ("<<" | ">>") a_expr

Ces opérateurs prennent des entiers comme arguments. Ils décalent le
premier argument vers la gauche ou vers la droite du nombre de bits
donné par le deuxième argument.

This operation can be customized using the special "__lshift__()" and
"__rshift__()" methods.

Un décalage à droite de *n* bits est défini comme la division entière
par "pow(2,n)". Un décalage à gauche de *n* bits est défini comme la
multiplication par "pow(2,n)".


6.9. Opérations binaires bit à bit
==================================

Chacune des trois opérations binaires bit à bit possède une priorité
différente :

   and_expr ::= shift_expr | and_expr "&" shift_expr
   xor_expr ::= and_expr | xor_expr "^" and_expr
   or_expr  ::= xor_expr | or_expr "|" xor_expr

The "&" operator yields the bitwise AND of its arguments, which must
be integers or one of them must be a custom object overriding
"__and__()" or "__rand__()" special methods.

The "^" operator yields the bitwise XOR (exclusive OR) of its
arguments, which must be integers or one of them must be a custom
object overriding "__xor__()" or "__rxor__()" special methods.

The "|" operator yields the bitwise (inclusive) OR of its arguments,
which must be integers or one of them must be a custom object
overriding "__or__()" or "__ror__()" special methods.


6.10. Comparaisons
==================

Au contraire du C, toutes les opérations de comparaison en Python
possèdent la même priorité, qui est plus faible que celle des
opérations arithmétiques, décalages ou binaires bit à bit. Toujours
contrairement au C, les expressions telles que "a < b < c" sont
interprétées comme elles le seraient conventionnellement en
mathématiques :

   comparison    ::= or_expr (comp_operator or_expr)*
   comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="
                     | "is" ["not"] | ["not"] "in"

Les comparaisons donnent des valeurs booléennes ("True" ou "False").
Cependant, les *méthodes de comparaison riche* définies par
l'utilisateur peuvent renvoyer des non-booléens. Dans ce cas, le
résultat de la comparaison est converti en booléen avec "bool()" dans
les contextes qui attendent un booléen.

Les comparaisons peuvent être enchaînées arbitrairement, par exemple
"x < y <= z" est équivalent à "x < y and y <= z", sauf que "y" est
évalué seulement une fois (mais dans les deux cas, "z" n'est pas
évalué du tout si "x < y" s'avère être faux).

Formellement, si *a*, *b*, *c* … *y*, *z* sont des expressions et
*op1*, *op2* … *opN* sont des opérateurs de comparaison, alors "a op1
b op2 c … y opN z" est équivalent à "a op1 b and b op2 c and … y opN
z", sauf que chaque expression est évaluée au maximum une fois.

Notez que "a op1 b op2 c" n'implique aucune comparaison entre *a* et
*c*. Ainsi, par exemple, "x < y > z" est parfaitement légal (mais
peut-être pas très élégant).


6.10.1. Comparaisons de valeurs
-------------------------------

Les opérateurs "<", ">", "==", ">=", "<=" et  "!=" comparent les
valeurs de deux objets. Les objets n'ont pas besoin d'être du même
type.

Le chapitre Objets, valeurs et types indique que les objets ont une
valeur (en plus d'un type et d'un identifiant). La valeur d'un objet
est une notion plutôt abstraite en Python : par exemple, il n'existe
pas de méthode canonique pour accéder à la valeur d'un objet. De la
même manière, il n'y a aucune obligation concernant la construction de
la valeur d'un objet, par exemple qu'elle prenne en compte toutes les
données de ses attributs. Les opérateurs de comparaison implémentent
une notion particulière de ce qu'est la valeur d'un objet. Vous pouvez
vous le représenter comme une définition indirecte de la valeur d'un
objet, *via* l'implémentation de leur comparaison.

Because all types are (direct or indirect) subtypes of "object", they
inherit the default comparison behavior from "object".  Types can
customize their comparison behavior by implementing *rich comparison
methods* like "__lt__()", described in Personnalisation de base.

Le comportement par défaut pour le test d'égalité ("==" et "!=") se
base sur les identifiants des objets. Ainsi, un test d'égalité entre
deux instances qui ont le même identifiant est vrai, un test d'égalité
entre deux instances qui ont des identifiants différents est faux. La
raison de ce choix est que Python souhaite que tous les objets soient
réflexifs, c'est-à-dire que "x is y" implique "x == y".

La relation d'ordre ("<", ">", "<=" et ">=") n'est pas fournie par
défaut ; une tentative se solde par une "TypeError". La raison de ce
choix est qu'il n'existe pas d'invariant similaire à celui de
l'égalité.

Le comportement du test d'égalité par défaut, à savoir que les
instances avec des identités différentes ne sont jamais égales, peut
être en contradiction avec les types qui définissent la « valeur »
d'un objet et se basent sur cette « valeur » pour l'égalité. De tels
types doivent personnaliser leurs tests de comparaison et, en fait,
c'est ce qu'ont fait un certain nombre de types natifs.

La liste suivante décrit le comportement des tests d'égalité pour les
types natifs les plus importants.

* Beaucoup de types numériques natifs (Types numériques — int, float,
  complex) et de types de la bibliothèque standard
  "fractions.Fraction" ainsi que "decimal.decimal" peuvent être
  comparés, au sein de leur propre classe ou avec d'autres objets de
  classes différentes. Une exception notable concerne les nombres
  complexes qui ne gèrent pas la relation d'ordre. Dans les limites
  des types concernés, la comparaison mathématique équivaut à la
  comparaison algorithmique, sans perte de précision.

  Les valeurs non numériques "float('NaN')" et
  "decimal.Decimal('NaN')" sont spéciales : toute comparaison entre un
  nombre et une valeur non numérique est fausse. Une implication
  contre-intuitive à cela est que les valeurs non numériques ne sont
  pas égales à elles-mêmes. Par exemple, avec "x = float('NaN')", les
  expressions "3 < x", "x < 3" et "x == x" sont toutes fausses, mais
  l’expression "x != x" est vraie. Ce comportement est en accord avec
  IEEE 754.

* "None" and "NotImplemented" are singletons.  **PEP 8** advises that
  comparisons for singletons should always be done with "is" or "is
  not", never the equality operators.

* Les séquences binaires (instances du type "bytes" ou "bytearray")
  peuvent être comparées au sein de la classe et entre classes. La
  comparaison est lexicographique, en utilisant la valeur numérique
  des éléments.

* Les chaînes de caractères (instances de "str") respectent l'ordre
  lexicographique en utilisant la valeur Unicode (le résultat de la
  fonction native "ord()") des caractères [3].

  Les chaînes de caractères et les séquences binaires ne peuvent pas
  être comparées directement.

* Les séquences (instances de "tuple", "list" ou "range") peuvent être
  comparées uniquement entre instances de même type, en sachant que
  les intervalles (*range*) ne gèrent pas la relation d'ordre. Le test
  d'égalité entre ces types renvoie faux et une comparaison entre
  instances de types différents lève une  "TypeError".

  Les séquences se comparent lexicographiquement en comparant les
  éléments correspondants. Les conteneurs natifs supposent
  généralement que les objets identiques sont égaux à eux-mêmes. Cela
  leur permet d'économiser les tests d’égalité pour des objets
  identiques afin d’améliorer les performances et de conserver leurs
  invariants internes.

  L'ordre lexicographique pour les collections natives fonctionne
  comme suit :

  * Deux collections sont égales si elles sont du même type, ont la
    même longueur et si les éléments correspondants de chaque paire
    sont égaux. Par exemple, "[1,2] == (1,2)" est faux car les types
    sont différents.

  * Les collections qui gèrent la relation d'ordre sont ordonnées
    comme leur premier élément différent (par exemple, "[1,2,x] <=
    [1,2,y]" a la même valeur que "x <= y"). Si un élément n'a pas de
    correspondant, la collection la plus courte est la plus petite
    (par exemple, "[1,2] < [1,2,3]" est vrai).

* Les tableaux de correspondances (instances de "dict") sont égales si
  et seulement si toutes leurs paires "(clé, valeur)" sont égales.
  L'égalité des clés et des valeurs met en œuvre la réflexivité.

  Les comparaisons ("<", ">", "<=" et ">=") lèvent "TypeError".

* Les ensembles (instances de "set" ou "frozenset") peuvent être
  comparés au sein de leur propre type et entre types différents.

  Les opérateurs d'inclusion et de sur-ensemble sont définis. Ces
  relations ne sont pas des relations d'ordre total (par exemple, les
  deux ensembles "{1,2}" et "{2,3}" ne sont pas égaux, l'un n'est pas
  inclus dans l'autre, l'un n'est pas un sur-ensemble de l'autre).
  Ainsi, les ensembles ne sont pas des arguments appropriés pour les
  fonctions qui dépendent d'un ordre total (par exemple, les fonctions
  "min()", "max()" et "sorted()" produisent des résultats indéfinis si
  on leur donne des listes d'ensembles en entrée).

  La comparaison des ensembles met en œuvre la réflexivité des
  éléments.

* La plupart des autres types natifs n'implémentent pas de méthodes de
  comparaisons, ils héritent donc du comportement par défaut.

Les classes définies par l'utilisateur qui particularisent les
opérations de comparaison doivent, si possible, respecter quelques
règles pour la cohérence :

* Le test d'égalité doit être réflexif. En d'autres termes, des objets
  identiques doivent être égaux :

     "x is y" implique "x == y"

* La comparaison doit être symétrique. En d'autres termes, les
  expressions suivantes doivent donner le même résultat :

     "x == y" et "y == x"

     "x != y" et "y != x"

     "x < y" et "y > x"

     "x <= y" et "y >= x"

* La comparaison doit être transitive. Les exemples suivants (liste
  non exhaustive) illustrent ce concept :

     "x > y and y > z" implique "x > z"

     "x < y and y <= z" implique "x < z"

* Si vous inversez la comparaison, cela doit en produire la négation
  booléenne. En d'autres termes, les expressions suivantes doivent
  produire le même résultat :

     "x == y" et "not x != y"

     "x < y" et "not x >= y" (pour une relation d'ordre total)

     "x > y" et "not x <= y" (pour une relation d'ordre total)

  Ces deux dernières expressions s'appliquent pour les collections
  totalement ordonnées (par exemple, les séquences mais pas les
  ensembles ou les tableaux de correspondances). Regardez aussi le
  décorateur "total_ordering()".

* Le résultat de "hash()" doit être cohérent avec l'égalité. Les
  objets qui sont égaux doivent avoir la même empreinte ou être
  marqués comme non-hachables.

Python ne vérifie pas ces règles de cohérence. En fait, l'utilisation
de valeurs non numériques est un exemple de non-respect de ces règles.


6.10.2. Opérations de tests d’appartenance à un ensemble
--------------------------------------------------------

Les opérateurs "in" et "not in" testent l’appartenance. "x in s"
s’évalue à "True" si *x* appartient à *s* et à "False" sinon. "x not
in s" renvoie la négation de "x in s". Tous les types séquences et
ensembles natifs gèrent ces opérateurs, ainsi que les dictionnaires
pour lesquels "in" teste si dictionnaire possède une clé donnée. Pour
les types conteneurs tels que les listes, *n*-uplets (*tuple*),
ensembles (*set*), ensembles figés (*frozen set*), dictionnaires
(*dict*) ou *collections.deque*, l’expression "x in y" est équivalente
à "any(x is e or x == e for e in y)".

Pour les chaînes de caractères et chaînes d'octets, "x in y" vaut
"True" si et seulement si *x* est une sous-chaîne de *y*. Un test
équivalent est "y.find(x) != -1". Une chaîne vide est considérée comme
une sous-chaîne de toute autre chaîne, ainsi """ in "abc"" renvoie
"True".

For user-defined classes which define the "__contains__()" method, "x
in y" returns "True" if "y.__contains__(x)" returns a true value, and
"False" otherwise.

For user-defined classes which do not define "__contains__()" but do
define "__iter__()", "x in y" is "True" if some value "z", for which
the expression "x is z or x == z" is true, is produced while iterating
over "y". If an exception is raised during the iteration, it is as if
"in" raised that exception.

Lastly, the old-style iteration protocol is tried: if a class defines
"__getitem__()", "x in y" is "True" if and only if there is a non-
negative integer index *i* such that "x is y[i] or x == y[i]", and no
lower integer index raises the "IndexError" exception.  (If any other
exception is raised, it is as if "in" raised that exception).

L'opérateur "not in" est défini comme produisant le contraire de "in".


6.10.3. Comparaisons d'identifiants
-----------------------------------

Les opérateurs "is" et "is not" testent l'égalité des identifiants des
objets : "x is y" est vrai si et seulement si *x* et *y* sont le même
objet. L'identifiant d'un objet est déterminé en utilisant la fonction
"id()". "x is not y" renvoie le résultat contraire de l'égalité des
identifiants [4].


6.11. Opérations booléennes
===========================

   or_test  ::= and_test | or_test "or" and_test
   and_test ::= not_test | and_test "and" not_test
   not_test ::= comparison | "not" not_test

In the context of Boolean operations, and also when expressions are
used by control flow statements, the following values are interpreted
as false: "False", "None", numeric zero of all types, and empty
strings and containers (including strings, tuples, lists,
dictionaries, sets and frozensets).  All other values are interpreted
as true.  User-defined objects can customize their truth value by
providing a "__bool__()" method.

L'opérateur "not" produit "True" si son argument est faux, "False"
sinon.

L'expression "x and y" commence par évaluer *x* ; si *x* est faux, sa
valeur est renvoyée ; sinon, *y* est évalué et la valeur résultante
est renvoyée.

L'expression "x or y" commence par évaluer *x* ; si *x* est vrai, sa
valeur est renvoyée ; sinon, *y* est évalué et la valeur résultante
est renvoyée.

Notez que ni "and" ni "or" ne restreignent la valeur et le type qu'ils
renvoient à "False" et "True" : ils renvoient le dernier argument
évalué. Ceci peut être utile, par exemple : si une chaîne "s" doit
être remplacée par une valeur par défaut si elle est vide,
l'expression "s or 'truc'" produit la valeur voulue. Comme "not" doit
créer une nouvelle valeur, il renvoie une valeur booléenne quel que
soit le type de son argument (par exemple, "not 'truc'" produit
"False" plutôt que "''".


6.12. Expressions d'affectation
===============================

   assignment_expression ::= [identifier ":="] expression

Une expression d'affectation (parfois aussi appelée « expression
nommée » ou « expression morse ») affecte l'"expression" à un
"identifiant" et renvoie la valeur de l'"expression".

Une utilisation classique concerne les correspondances d'expressions
rationnelles :

   if matching := pattern.search(data):
       do_something(matching)

Ou lorsqu'on traite le contenu d'un fichier par morceaux :

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

Assignment expressions must be surrounded by parentheses when used as
expression statements and when used as sub-expressions in slicing,
conditional, lambda, keyword-argument, and comprehension-if
expressions and in "assert", "with", and "assignment" statements. In
all other places where they can be used, parentheses are not required,
including in "if" and "while" statements.

Nouveau dans la version 3.8: Voir la **PEP 572** pour plus de détails
sur les expressions d’affectation.


6.13. Expressions conditionnelles
=================================

   conditional_expression ::= or_test ["if" or_test "else" expression]
   expression             ::= conditional_expression | lambda_expr

Les expressions conditionnelles (parfois appelées « opérateur ternaire
») sont les moins prioritaires de toutes les opérations Python.

L'expression "x if C else y" commence par évaluer la condition *C*. Si
*C* est vrai, alors *x* est évalué et sa valeur est renvoyée ; sinon,
*y* est évalué et sa valeur est renvoyée.

Voir la **PEP 308** pour plus de détails sur les expressions
conditionnelles.


6.14. Expressions lambda
========================

   lambda_expr ::= "lambda" [parameter_list] ":" expression

Les expressions lambda sont utilisées pour créer des fonctions
anonymes. L'expression "lambda parameters: expression" produit un
objet fonction. Cet objet anonyme se comporte comme un objet fonction
défini par :

   def <lambda>(parameters):
       return expression

Voir la section Définition de fonctions pour la syntaxe des listes de
paramètres. Notez que les fonctions créées par des expressions lambda
ne peuvent pas contenir d'instructions ou d'annotations.


6.15. Listes d'expressions
==========================

   expression_list    ::= expression ("," expression)* [","]
   starred_list       ::= starred_item ("," starred_item)* [","]
   starred_expression ::= expression | (starred_item ",")* [starred_item]
   starred_item       ::= assignment_expression | "*" or_expr

Sauf lorsqu'elle fait partie d'un agencement de liste ou d'ensemble,
une liste d'expressions qui contient au moins une virgule produit un
*n*-uplet. La longueur du *n*-uplet est le nombre d'expressions dans
la liste. Les expressions sont évaluées de la gauche vers la droite.

Un astérisque "*" indique *dépaquetage d'itérable* (*iterable
unpacking* en anglais). Son opérande doit être un *iterable*.
L'itérable est développé en une séquence d'éléments qui sont inclus
dans un nouvel objet *n*-uplet, liste ou ensemble à l'emplacement du
dépaquetage.

Nouveau dans la version 3.5: dépaquetage d'itérables dans les listes
d'expressions, proposé à l'origine par la **PEP 448**.

A trailing comma is required only to create a one-item tuple, such as
"1,"; it is optional in all other cases. A single expression without a
trailing comma doesn't create a tuple, but rather yields the value of
that expression. (To create an empty tuple, use an empty pair of
parentheses: "()".)


6.16. Ordre d'évaluation
========================

Python évalue les expressions de la gauche vers la droite. Remarquez
que lors de l'évaluation d'une affectation, la partie droite de
l'affectation est évaluée avant la partie gauche.

Dans les lignes qui suivent, les expressions sont évaluées suivant
l'ordre arithmétique de leurs suffixes :

   expr1, expr2, expr3, expr4
   (expr1, expr2, expr3, expr4)
   {expr1: expr2, expr3: expr4}
   expr1 + expr2 * (expr3 - expr4)
   expr1(expr2, expr3, *expr4, **expr5)
   expr3, expr4 = expr1, expr2


6.17. Priorités des opérateurs
==============================

Le tableau suivant résume les priorités des opérateurs en Python, du
plus prioritaire (portée la plus courte) au moins prioritaire (portée
la plus grande). Les opérateurs qui sont dans la même case ont la même
priorité. À moins que la syntaxe ne soit explicitement indiquée, les
opérateurs sont binaires. Les opérateurs dans la même case regroupent
de la gauche vers la droite (sauf pour la puissance et les expressions
conditionnelles qui regroupent de la droite vers la gauche).

Notez que les comparaisons, les tests d'appartenance et les tests
d'identifiants possèdent tous la même priorité et s'enchaînent de la
gauche vers la droite comme décrit dans la section Comparaisons.

+-------------------------------------------------+---------------------------------------+
| Opérateur                                       | Description                           |
|=================================================|=======================================|
| "(expressions…)",  "[expressions…]", "{key:     | Expression de liaison ou parenthèse,  |
| value…}", "{expressions…}"                      | affichage de liste, affichage de      |
|                                                 | dictionnaire, affichage de *set*      |
+-------------------------------------------------+---------------------------------------+
| "x[indice]", "x[indice:indice]",                | indiçage, tranches, appel, référence  |
| "x(arguments…)", "x.attribut"                   | à un attribut                         |
+-------------------------------------------------+---------------------------------------+
| "await x"                                       | Expression "await"                    |
+-------------------------------------------------+---------------------------------------+
| "**"                                            | Puissance [5]                         |
+-------------------------------------------------+---------------------------------------+
| "+x", "-x", "~x"                                | NOT (positif, négatif, bit à bit)     |
+-------------------------------------------------+---------------------------------------+
| "*", "@", "/", "//", "%"                        | Multiplication, multiplication de     |
|                                                 | matrices, division, division entière, |
|                                                 | reste [6]                             |
+-------------------------------------------------+---------------------------------------+
| "+", "-"                                        | Addition et soustraction              |
+-------------------------------------------------+---------------------------------------+
| "<<", ">>"                                      | décalages                             |
+-------------------------------------------------+---------------------------------------+
| "&"                                             | AND (bit à bit)                       |
+-------------------------------------------------+---------------------------------------+
| "^"                                             | XOR (bit à bit)                       |
+-------------------------------------------------+---------------------------------------+
| "|"                                             | OR (bit à bit)                        |
+-------------------------------------------------+---------------------------------------+
| "in", "not in", "is", "is not", "<", "<=", ">", | Comparaisons, y compris les tests     |
| ">=", "!=", "=="                                | d'appartenance et les tests           |
|                                                 | d'identifiants                        |
+-------------------------------------------------+---------------------------------------+
| "not x"                                         | NOT (booléen)                         |
+-------------------------------------------------+---------------------------------------+
| "and"                                           | AND (booléen)                         |
+-------------------------------------------------+---------------------------------------+
| "or"                                            | OR (booléen)                          |
+-------------------------------------------------+---------------------------------------+
| "if" -- "else"                                  | Expressions conditionnelles           |
+-------------------------------------------------+---------------------------------------+
| "lambda"                                        | Expression lambda                     |
+-------------------------------------------------+---------------------------------------+
| ":="                                            | Expression d'affectation              |
+-------------------------------------------------+---------------------------------------+

-[ Notes ]-

[1] Bien que "abs(x%y) < abs(y)" soit vrai mathématiquement, ce n'est
    pas toujours vrai pour les nombres à virgule flottante en raison
    des arrondis. Par exemple, en supposant que Python tourne sur une
    plateforme où les *float* sont des nombres à double précision IEEE
    754, afin que "-1e-100 % 1e100" soit du même signe que "1e100", le
    résultat calculé est "-1e-100 + 1e100", qui vaut exactement
    "1e100" dans ce standard. Or, la fonction "math.fmod()" renvoie un
    résultat dont le signe est le signe du premier argument,
    c'est-à-dire "-1e-100" dans ce cas. La meilleure approche dépend
    de l'application.

[2] Si x est très proche d'un multiple entier de y, il est possible
    que "x/y" soit supérieur de un par rapport à "(x-x%y)//y" en
    raison des arrondis. Dans de tels cas, Python renvoie le second
    résultat afin d'avoir "divmod(x,y)[0] * y + x % y" le plus proche
    de "x".

[3] Le standard Unicode distingue les *points codes* (*code points* en
    anglais, par exemple *U+0041*) et les *caractères abstraits*
    (*abstract characters* en anglais, par exemple « LATIN CAPITAL
    LETTER A »). Bien que la plupart des caractères abstraits de
    l'Unicode ne sont représentés que par un seul point code, il y a
    un certain nombre de caractères abstraits qui peuvent être
    représentés par une séquence de plus qu'un point code. Par
    exemple, le caractère abstrait « LATIN CAPITAL LETTER C WITH
    CEDILLA » peut être représenté comme un unique *caractère
    précomposé* au point code *U+00C7*, ou en tant que séquence d'un
    *caractère de base* à la position *U+0043* (LATIN CAPITAL LETTER
    C) du code, suivi par un *caractère combiné* à la position
    *U+0327* (*COMBINING CEDILLA*) du code.

    Les opérateurs de comparaison des chaînes opèrent au niveau des
    points codes Unicode. Cela peut être déroutant pour des humains.
    Par exemple, ""\u00C7" == "\u0043\u0327"" renvoie "False", bien
    que les deux chaînes représentent le même caractère abstrait
    "LATIN CAPITAL LETTER C WITH CEDILLA".

    Pour comparer des chaînes au niveau des caractères abstraits (afin
    d'avoir quelque chose d'intuitif pour les humains), utilisez
    "unicodedata.normalize()".

[4] En raison du ramasse-miettes automatique et de la nature dynamique
    des descripteurs, vous pouvez être confronté à un comportement
    semblant bizarre lors de certaines utilisations de l'opérateur
    "is", par exemple si cela implique des comparaisons entre des
    méthodes d'instances ou des constantes. Allez vérifier dans la
    documentation pour plus d'informations.

[5] L'opérateur puissance "**" est moins prioritaire qu'un opérateur
    unaire arithmétique ou bit à bit sur sa droite. Ainsi, "2**-1"
    vaut "0.5".

[6] L'opérateur "%" est aussi utilisé pour formater les chaînes de
    caractères ; il y possède la même priorité.
