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é <private name>* 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 une
clause "for" or "async for" suivie par des clauses "for" ou "async
for" additionnelles facultatives et, possiblement, des expressions
"await". Si la compréhension contient soit des clauses "async for",
soit des expressions "await", 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.


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 muable, 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       ::= "{" [key_datum_list | dict_comprehension] "}"
   key_datum_list     ::= key_datum ("," key_datum)* [","]
   key_datum          ::= 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 donnée 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 muables). 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
<asynchronous generator expression>*. 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_expression ::= "yield" [expression_list | "from" expression]

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.

When a generator function is called, it returns an iterator known as a
generator.  That generator then controls the execution of the
generator function.  The execution starts when one of the generator's
methods is called. At that time, the execution proceeds to the first
yield expression, where it is suspended again, returning the value of
"expression_list" to the generator's caller, or "None" if
"expression_list" is omitted. By suspended, we mean that all local
state is retained, including the current bindings of local variables,
the instruction pointer, the internal evaluation stack, and the state
of any exception handling. When the execution is resumed by calling
one of the generator's methods, the function can proceed exactly as if
the yield expression were just another external call.  The value of
the yield expression after resuming depends on the method which
resumed the execution.  If "__next__()" is used (typically via either
a "for" or the "next()" builtin) then the result is "None".
Otherwise, if "send()" is used, then the result will be the value
passed in to that method.

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'assignation.

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érateurs.

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érateur. 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".

   For backwards compatibility, however, the second signature is
   supported, following a convention from older versions of Python.
   The *type* argument should be an exception class, and *value*
   should be an exception instance. If the *value* is not provided,
   the *type* constructor is called to get an instance. If *traceback*
   is provided, it is set on the exception, otherwise any existing
   "__traceback__" attribute stored in *value* may be cleared.

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.

To take care of finalization upon event loop termination, an event
loop should define a *finalizer* function which takes an asynchronous
generator-iterator and presumably calls "aclose()" and executes the
coroutine. This  *finalizer* may be registered by calling
"sys.set_asyncgen_hooks()". When first iterated over, an asynchronous
generator-iterator will store the registered *finalizer* to be called
upon finalization. For a reference example of a *finalizer* method see
the implementation of "asyncio.Loop.shutdown_asyncgens" in
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érateur 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

La primaire doit s'évaluer à un objet d'un type qui gère les
références aux attributs, ce qui est le cas de la plupart des objets.
Cet objet doit alors produire l'attribut dont le nom est « identifier
». Cette production peut être personnalisée en surchargeant la méthode
"__getattr__()". Si l'attribut n'est pas disponible, une exception
"AttributeError" est levée. Sinon, le type et la valeur de l'objet
produit sont déterminés par l'objet. Plusieurs évaluations successives
d'une référence à un même attribut peuvent produire différents objets.


6.3.2. Sélections
-----------------

L'indiçage d'une instance de classe containeur 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".

La syntaxe formelle ne traite pas des cas d'indices négatifs dans les
*séquences* ; cependant, toutes les séquences natives possèdent une
méthode "__getitem__()" qui interprète les indices négatifs en
ajoutant la longueur de la séquence à l'indice (de manière à ce que
"x[-1]" sélectionne le dernier élément de "x"). La valeur résultante
doit être un entier positif ou nul, inférieur au nombre d'éléments
dans la séquence ; la sélection désigne alors l'élément dont l'indice
est cette valeur (en comptant à partir de zéro). Comme la gestion des
indices négatifs et des tranches est faite par la méthode
"__getitem__()", les sous-classes qui surchargent cette méthode
doivent aussi savoir les gérer, de manière explicite.

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 assignations 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).

La sémantique pour une tranche est définie comme suit. La primaire est
indicée (en utilisant la même méthode "__getitem__()" que pour les
sélections normales) avec une clé qui est construite à partir de la
liste de tranches (*slice_list* dans la grammaire), de cette manière :
si la liste de tranches contient au moins une virgule (","), la clé
est un *n*-uplet contenant la conversion des éléments de la tranche ;
sinon, la conversion du seul élément de la tranche est la clé. La
conversion d'un élément de tranche qui est une expression est cette
expression. La conversion d'une tranche en tant que telle est un objet
*slice* (voir la section Hiérarchie des types standards) dont les
attributs "start", "stop" et "step" sont les valeurs des expressions
données pour la borne inférieure (*lower_bound* dans la grammaire), la
borne supérieure (*upper_bound* dans la grammaire) et le pas (*stride*
dans la grammaire), respectivement. En cas d'expression manquante, la
valeur par défaut est "None".


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.

La primaire doit s'évaluer à un objet appelable (une fonction définie
par l'utilisateur, une fonction native, une méthode d'objet natif, un
objet de classe, une méthode d'instance de classe ou tout objet
possédant une méthode "__call__()" est un appelable). Toutes les
expressions des arguments sont évaluées avant que l'appel ne soit
exécuté. Référez-vous à la section Définition de fonctions pour la
syntaxe des listes de *paramètres* formels.

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 par mot-clé, 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, la valeur de l'argument est placée 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 spécifiés par mot-clé. 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 par mot-clé 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 par mot-clé 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 par mot-clé 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 hypothétique.

If the syntax "**expression" appears in the function call,
"expression" must evaluate to a *mapping*, the contents of which are
treated as additional keyword arguments. If a parameter matching a key
has already been given a value (by an explicit keyword argument, or
from another unpacking), a "TypeError" exception is raised.

When "**expression" is used, each key in this mapping must be a
string. Each value from the mapping is assigned to the first formal
parameter eligible for keyword assignment whose name is equal to the
key. A key need not be a Python identifier (e.g. ""max-temp °F"" is
acceptable, although it will not match any formal parameter that could
be declared). If there is no match to a formal parameter the key-value
pair is collected by the "**" parameter, if there is one, or if there
is not, a "TypeError" exception is raised.

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 :
   la classe doit définir une méthode "__call__()" ; l'effet est le
   même que si cette méthode était appelée.


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").

La méthode spéciale qui permet de surcharger cet opérateur est
"__pow__()".


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

L'opérateur unaire "-" (moins) produit l'opposé de son argument
numérique (la méthode spéciale qui le surcharge est "__neg__()") ;

L'opérateur unaire "+" (plus) produit son argument numérique inchangé
(surcharge par la méthode "__pos__()") ;

L'opérateur unaire "~" (inversion) produit l'inversion bit à bit de
son argument entier. L'inversion bit à bit de "x" est définie comme
"-(x+1)". Elle ne s'applique qu'aux nombres entiers et aux objets
allogènes qui surchargent la méthode spéciale "__invert__()".

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.

Les méthodes spéciales qui permettent de surcharger cet opérateur sont
"__mul__()" et "__rmul__()".

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".

Les méthodes spéciales qui permettent de surcharger ces opérations
sont "__truediv__()" et "__floordiv__()".

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.

La méthode spéciale qui permet de surcharger cette opération est
"__mod__()".

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.

Les méthodes spéciales qui permettent de surcharger cette opération
sont "__add__()" et "__radd__()".

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

La méthode spéciale qui permet de surcharger cette opération est
"__sub__()".


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.

Les méthodes spéciales qui permettent de surcharger ces opérations
sont "__lshift__()" et "__rshift__()".

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

L'opérateur "&" produit le ET logique de ses arguments. Ils doivent
être des entiers, sauf si celui de gauche surcharge la méthode
spéciale "__and__()", ou celui de droite la méthode "__rand__()".

L'opérateur "^" produit le OU EXCLUSIF (XOR) logique de ses arguments.
Ils doivent être des entiers, sauf à surcharger "__xor__()" ou
"__rxor__()".

L'opérateur "|" produit le OU logique de ses arguments. Ils doivent
être des entiers, sauf à surcharger "__or__()" ou "__ror__()".


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.

Comme tous les types sont des sous-types (directs ou indirects) de la
classe "object", ils héritent du comportement de comparaison par
défaut de "object".  Les types peuvent personnaliser le comportement
des comparaisons en implémentant des *méthodes de comparaisons
riches*, comme "__lt__()", décrites dans 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" et "NotImplemented" sont des singletons. **PEP 8** conseille
  de toujours comparer les singletons en utilisant soit "is" soit "is
  not", jamais les autres opérateurs.

* 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).

* Mappings (instances of "dict") compare equal if and only if they
  have equal "(key, value)" pairs. Equality comparison of the keys and
  values enforces reflexivity.

  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 allogènes 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".

Pour les classes allogènes qui définissent la méthode
"__contains__()", "x in y" renvoie "True" si "y.__contains__(x)"
renvoie vrai, et "False" sinon.

Pour les classes allogènes qui ne définissent pas "__contains__()"
mais qui définissent "__iter__()", "x in y" vaut "True" s'il existe
une valeur "z" telle que l'expression "x is z or x == z" renvoie vrai
lors de l'itération sur "y". Si une exception est levée pendant
l'itération, c'est comme si "in" avait levé cette exception.

Enfin, le protocole d'itération « à l'ancienne » est essayé : si la
classe définit "__getitem__()", "x in y" est "True" si et seulement si
il existe un entier positif ou nul *i*, représentant l'indice, tel que
"x is y[i] or x == y[i]" et qu'aucun indice inférieur ne lève
d'exception "IndexError" (si toute autre exception est levée, c'est
comme si "in" avait levé cette 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

Dans le contexte des opérations booléennes et quand des expressions
sont utilisées par des instructions de contrôle du flux d'exécution,
les valeurs suivantes sont considérées comme fausses : "False",
"None", zéro quel que soit le type, la chaîne vide et tout conteneur
vide (y compris les chaînes, *n*-uplets, listes, dictionnaires,
ensembles, ensembles figés). Toutes les autres valeurs sont
considérées comme vraies. Les objets allogènes peuvent personnaliser
leur table de vérité en implémentant une méthode "__bool__()".

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
sub-expressions in slicing, conditional, lambda, keyword-argument, and
comprehension-if expressions and in "assert" and "with" 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**.

La virgule finale est nécessaire pour créer un singleton (c'est-à-dire
un n-uplet composé d'un seul élément) : elle est optionnelle dans tous
les autres cas. Une expression seule sans virgule finale ne crée pas
un *n*-uplet mais produit la valeur de cette expression (pour créer un
*n*-uplet vide, utilisez une paire de parenthèses vide : "()").


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

Python évalue les expressions de la gauche vers la droite. Remarquez
que lors de l'évaluation d'une assignation, la partie droite de
l'assignation 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 qui regroupe 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é.
