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

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

**Syntax Notes:** In this and the following chapters, grammar notation
will be used to describe syntax, not lexical analysis.

When (one alternative of) a syntax rule has the form:

   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
==============================

When a description of an arithmetic operator below uses the phrase
"the numeric arguments are converted to a common real type", this
means that the operator implementation for built-in numeric types
works as described in the Numeric Types section of the standard
library documentation.

Some additional rules apply for certain operators and non-numeric
operands (for example, a string as a left argument to the "%"
operator). Extensions must define their own conversion behavior.


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

Atoms are the most basic elements of expressions. The simplest atoms
are names or literals. Forms enclosed in parentheses, brackets or
braces are also categorized syntactically as atoms.

Formally, the syntax for atoms is:

   atom:
      | 'True'
      | 'False'
      | 'None'
      | '...'
      | identifier
      | literal
      | enclosure
   enclosure:
      | parenth_form
      | list_display
      | dict_display
      | set_display
      | generator_expression
      | yield_atom


6.2.1. Built-in constants
-------------------------

The keywords "True", "False", and "None" name built-in constants. The
token "..." names the "Ellipsis" constant.

Evaluation of these atoms yields the corresponding value.

Note:

  Several more built-in constants are available as global variables,
  but only the ones mentioned here are keywords. In particular, these
  names cannot be reassigned or used as attributes:

     >>> False = 123
       File "<input>", line 1
        False = 123
        ^^^^^
     SyntaxError: cannot assign to False


6.2.2. Identifiants (noms)
--------------------------

Un identifiant qui apparaît en tant qu'atome est un nom. Lisez la
section Names (identifiers and keywords) 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".


6.2.2.1. Private name mangling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When an identifier that textually occurs in a class definition begins
with two or more underscore characters and does not end in two or more
underscores, it is considered a *private name* of that class.

Voir aussi: The class specifications.

More precisely, private names are transformed to a longer form before
code is generated for them.  If the transformed name is longer than
255 characters, implementation-defined truncation may happen.

The transformation is independent of the syntactical context in which
the identifier is used but only the following private identifiers are
mangled:

* Any name used as the name of a variable that is assigned or read or
  any name of an attribute being accessed.

  The "__name__" attribute of nested functions, classes, and type
  aliases is however not mangled.

* The name of imported modules, e.g., "__spam" in "import __spam". If
  the module is part of a package (i.e., its name contains a dot), the
  name is *not* mangled, e.g., the "__foo" in "import __foo.bar" is
  not mangled.

* The name of an imported member, e.g., "__f" in "from spam import
  __f".

The transformation rule is defined as follows:

* The class name, with leading underscores removed and a single
  leading underscore inserted, is inserted in front of the identifier,
  e.g., the identifier "__spam" occurring in a class named "Foo",
  "_Foo" or "__Foo" is transformed to "_Foo__spam".

* If the class name consists only of underscores, the transformation
  is the identity, e.g., the identifier "__spam" occurring in a class
  named "_" or "__" is left as is.


6.2.3. Littéraux
----------------

A *literal* is a textual representation of a value. Python supports
numeric, string and bytes literals. Format strings and template
strings are treated as string literals.

Numeric literals consist of a single "NUMBER" token, which names an
integer, floating-point number, or an imaginary number. See the
Littéraux numériques section in Lexical analysis documentation for
details.

String and bytes literals may consist of several tokens. See section
Concaténation de chaînes de caractères for details.

Note that negative and complex numbers, like "-3" or "3+4.2j", are
syntactically not literals, but unary or binary arithmetic operations
involving the "-" or "+" operator.

Evaluation of a literal yields an object of the given type ("int",
"float", "complex", "str", "bytes", or "Template") with the given
value. The value may be approximated in the case of floating-point and
imaginary literals.

The formal grammar for literals is:

   literal: strings | NUMBER


6.2.3.1. Literals and object identity
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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.

CPython implementation detail: For example, in CPython, *small*
integers with the same value evaluate to the same object:

   >>> x = 7
   >>> y = 7
   >>> x is y
   True

However, large integers evaluate to different objects:

   >>> x = 123456789
   >>> y = 123456789
   >>> x is y
   False

This behavior may change in future versions of CPython. In particular,
the boundary between "small" and "large" integers has already changed
in the past.CPython will emit a "SyntaxWarning" when you compare
literals using "is":

   >>> x = 7
   >>> x is 7
   <input>:1: SyntaxWarning: "is" with 'int' literal. Did you mean "=="?
   True

See Quand puis-je raisonnablement utiliser le test d'identité is ? for
more information.

Template strings are immutable but may reference mutable objects as
"Interpolation" values. For the purposes of this section, two
t-strings have the "same value" if both their structure and the
*identity* of the values match.

**Particularité de l'implémentation CPython :** Currently, each
evaluation of a template string results in a different object.


6.2.3.2. Concaténation de chaînes de caractères
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Multiple adjacent string or bytes literals, possibly using different
quoting conventions, are allowed, and their meaning is the same as
their concatenation:

   >>> "hello" 'world'
   "helloworld"

This feature is defined at the syntactical level, so it only works
with literals. To concatenate string expressions at run time, the '+'
operator may be used:

   >>> greeting = "Hello"
   >>> space = " "
   >>> name = "Blaise"
   >>> print(greeting + space + name)   # not: print(greeting space name)
   Hello Blaise

Literal concatenation can freely mix raw strings, triple-quoted
strings, and formatted string literals. For example:

   >>> "Hello" r', ' f"{name}!"
   "Hello, Blaise!"

This feature can be used to reduce the number of backslashes needed,
to split long strings conveniently across long lines, or even to add
comments to parts of strings. For example:

   re.compile("[A-Za-z_]"       # letter or underscore
              "[A-Za-z0-9_]*"   # letter, digit or underscore
             )

However, bytes literals may only be combined with other byte literals;
not with string literals of any kind. Also, template string literals
may only be combined with other template string literals:

   >>> t"Hello" t"{name}!"
   Template(strings=('Hello', '!'), interpolations=(...))

Formally:

   strings: (STRING | fstring)+ | tstring+


6.2.4. 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.5. 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: flexible_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]

The comprehension consists of a single expression followed by at least
one "for" clause and zero or more "for" or "if" clauses.  In this
case, the elements of the new container are those that would be
produced by considering each of the "for" or "if" clauses a block,
nesting from left to right, and evaluating the expression to produce
an element each time the innermost block is reached.  If the
expression is starred, the result will instead be unpacked to produce
zero or more elements.

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.

Since Python 3.6, in an "async def" function, an "async for" clause
may be used to iterate over a *asynchronous iterator*. A comprehension
in an "async def" function may consist of either a "for" or "async
for" clause following the leading expression, may contain additional
"for" or "async for" clauses, and may also use "await" expressions.

If a comprehension contains "async for" clauses, or if it contains
"await" expressions or other asynchronous comprehensions anywhere
except the iterable expression in the leftmost "for" clause, it is
called an *asynchronous comprehension*. An asynchronous comprehension
may suspend the execution of the coroutine function in which it
appears. See also **PEP 530**.

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

Modifié dans la version 3.15: Unpacking with the "*" operator is now
allowed in the expression.


6.2.6. Agencements de listes
----------------------------

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

   list_display: "[" [flexible_expression_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.7. 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: "{" (flexible_expression_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.8. 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_comprehension: dict_item comp_for
   dict_item:          expression ":" expression | "**" or_expr

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.

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

A dict comprehension may take one of two forms:

* The first form  uses two expressions separated with a colon followed
  by the usual "for" and "if" clauses.  When the comprehension is run,
  the resulting key and value elements are inserted in the new
  dictionary in the order they are produced.

* The second form uses a single expression prefixed by the "**"
  dictionary unpacking operator followed by the usual "for" and "if"
  clauses.  When the comprehension is evaluated, the expression is
  evaluated and then unpacked, inserting zero or more key/value pairs
  into the new dictionary.

Both forms of dictionary comprehension retain the property that if the
same key is specified multiple times, the associated value in the
resulting dictionary will be the last one specified.

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

Modifié dans la version 3.15: Unpacking with the "**" operator is now
allowed in dictionary comprehensions.


6.2.9. 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: "(" flexible_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.

Variables used in the generator expression are evaluated lazily when
the "__next__()" method is called for the generator object (in the
same fashion as normal generators).  However, the iterable expression
in the leftmost "for" clause is immediately evaluated, and the
*iterator* is immediately created for that iterable, so that an error
produced while creating the iterator will be emitted at the point
where the generator expression is defined, rather than at the point
where the first value is retrieved. Subsequent "for" clauses and any
filter condition in the leftmost "for" clause cannot be evaluated in
the enclosing scope as they may depend on the values obtained from the
leftmost iterable. For example: "(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).

Ajouté 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.10. Expressions "yield"
---------------------------

   yield_atom:       "(" yield_expression ")"
   yield_from:       "yield" "from" expression
   yield_expression: "yield" yield_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.

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
"yield_list" to the generator's caller, or "None" if "yield_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'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.10.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__()

   Starts the execution of a generator function or resumes it at the
   last executed yield expression.  When a generator function is
   resumed with a "__next__()" method, the current yield expression
   always evaluates to "None".  The execution then continues to the
   next yield expression, where the generator is suspended again, and
   the value of the "yield_list" is returned to "__next__()"'s caller.
   If the generator exits without yielding another value, a
   "StopIteration" exception is raised.

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

   Modifié dans la version 3.12: The second signature (type[, value[,
   traceback]]) is deprecated and may be removed in a future version
   of Python.

generator.close()

   Raises a "GeneratorExit" exception at the point where the generator
   function was paused (equivalent to calling "throw(GeneratorExit)").
   The exception is raised by the yield expression where the generator
   was paused. If the generator function catches the exception and
   returns a value, this value is returned from "close()".  If the
   generator function is already closed, or raises "GeneratorExit" (by
   not catching the exception), "close()" returns "None".  If the
   generator yields a value, a "RuntimeError" is raised.  If the
   generator raises any other exception, it is propagated to the
   caller.  If the generator has already exited due to an exception or
   normal exit, "close()" returns "None" and has no other effect.

   Modifié dans la version 3.13: If a generator returns a value upon
   being closed, the value is returned by "close()".


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

Calling one of the asynchronous generator's methods returns an
*awaitable* object, and the execution starts when this object is
awaited on. At that time, the execution proceeds to the first yield
expression, where it is suspended again, returning the value of
"yield_list" to the awaiting coroutine. As with a generator,
suspension means 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 awaiting on the next object returned
by the asynchronous 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 "__anext__()" is used then the result
is "None". Otherwise, if "asend()" is used, then the result will be
the value passed in to that method.

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

async agen.__anext__()

   Returns an awaitable which when run starts to execute the
   asynchronous generator or resumes it at the last executed yield
   expression.  When an asynchronous generator function is resumed
   with an "__anext__()" method, the current yield expression always
   evaluates to "None" in the returned awaitable, which when run will
   continue to the next yield expression. The value of the
   "yield_list" of the yield expression is the value of the
   "StopIteration" exception raised by the completing coroutine.  If
   the asynchronous generator exits without yielding another value,
   the awaitable instead raises a "StopAsyncIteration" exception,
   signalling that the asynchronous iteration has completed.

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

async agen.asend(value)

   Returns an awaitable which when run resumes the execution of the
   asynchronous generator. As with the "send()" method for a
   generator, this "sends" a value into the asynchronous generator
   function, and the *value* argument becomes the result of the
   current yield expression. The awaitable returned by the "asend()"
   method will return the next value yielded by the generator as the
   value of the raised "StopIteration", or raises "StopAsyncIteration"
   if the asynchronous generator exits without yielding another value.
   When "asend()" is called to start the asynchronous generator, it
   must be called with "None" as the argument, because there is no
   yield expression that could receive the value.

async agen.athrow(value)
async 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*.

   Modifié dans la version 3.12: The second signature (type[, value[,
   traceback]]) is deprecated and may be removed in a future version
   of Python.

async 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 | 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. Subscriptions and slicings
---------------------------------

The *subscription* syntax is usually used for selecting an element
from a container -- for example, to get a value from a "dict":

   >>> digits_by_name = {'one': 1, 'two': 2}
   >>> digits_by_name['two']  # Subscripting a dictionary using the key 'two'
   2

In the subscription syntax, the object being subscribed -- a primary
-- is followed by a *subscript* in square brackets. In the simplest
case, the subscript is a single expression.

Depending on the type of the object being subscribed, the subscript is
sometimes called a *key* (for mappings), *index* (for sequences), or
*type argument* (for *generic types*). Syntactically, these are all
equivalent:

   >>> colors = ['red', 'blue', 'green', 'black']
   >>> colors[3]  # Subscripting a list using the index 3
   'black'

   >>> list[str]  # Parameterizing the list type using the type argument str
   list[str]

At runtime, the interpreter will evaluate the primary and the
subscript, and call the primary's "__getitem__()" or
"__class_getitem__()" *special method* with the subscript as argument.
For more details on which of these methods is called, see
__class_getitem__ contre __getitem__.

To show how subscription works, we can define a custom object that
implements "__getitem__()" and prints out the value of the subscript:

   >>> class SubscriptionDemo:
   ...     def __getitem__(self, key):
   ...         print(f'subscripted with: {key!r}')
   ...
   >>> demo = SubscriptionDemo()
   >>> demo[1]
   subscripted with: 1
   >>> demo['a' * 3]
   subscripted with: 'aaa'

See "__getitem__()" documentation for how built-in types handle
subscription.

Subscriptions may also be used as targets in assignment or deletion
statements. In these cases, the interpreter will call the subscripted
object's "__setitem__()" or "__delitem__()" *special method*,
respectively, instead of "__getitem__()".

   >>> colors = ['red', 'blue', 'green', 'black']
   >>> colors[3] = 'white'  # Setting item at index
   >>> colors
   ['red', 'blue', 'green', 'white']
   >>> del colors[3]  # Deleting item at index 3
   >>> colors
   ['red', 'blue', 'green']

All advanced forms of *subscript* documented in the following sections
are also usable for assignment and deletion.


6.3.2.1. Tranches
~~~~~~~~~~~~~~~~~

A more advanced form of subscription, *slicing*, is commonly used to
extract a portion of a sequence. In this form, the subscript is a
*slice*: up to three expressions separated by colons. Any of the
expressions may be omitted, but a slice must contain at least one
colon:

   >>> number_names = ['zero', 'one', 'two', 'three', 'four', 'five']
   >>> number_names[1:3]
   ['one', 'two']
   >>> number_names[1:]
   ['one', 'two', 'three', 'four', 'five']
   >>> number_names[:3]
   ['zero', 'one', 'two']
   >>> number_names[:]
   ['zero', 'one', 'two', 'three', 'four', 'five']
   >>> number_names[::2]
   ['zero', 'two', 'four']
   >>> number_names[:-3]
   ['zero', 'one', 'two']
   >>> del number_names[4:]
   >>> number_names
   ['zero', 'one', 'two', 'three']

When a slice is evaluated, the interpreter constructs a "slice" object
whose "start", "stop" and "step" attributes, respectively, are the
results of the expressions between the colons. Any missing expression
evaluates to "None". This "slice" object is then passed to the
"__getitem__()" or "__class_getitem__()" *special method*, as above.

   # continuing with the SubscriptionDemo instance defined above:
   >>> demo[2:3]
   subscripted with: slice(2, 3, None)
   >>> demo[::'spam']
   subscripted with: slice(None, None, 'spam')


6.3.2.2. Comma-separated subscripts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The subscript can also be given as two or more comma-separated
expressions or slices:

   # continuing with the SubscriptionDemo instance defined above:
   >>> demo[1, 2, 3]
   subscripted with: (1, 2, 3)
   >>> demo[1:2, 3]
   subscripted with: (slice(1, 2, None), 3)

This form is commonly used with numerical libraries for slicing multi-
dimensional data. In this case, the interpreter constructs a "tuple"
of the results of the expressions or slices, and passes this tuple to
the "__getitem__()" or "__class_getitem__()" *special method*, as
above.

The subscript may also be given as a single expression or slice
followed by a comma, to specify a one-element tuple:

   >>> demo['spam',]
   subscripted with: ('spam',)


6.3.2.3. "Starred" subscriptions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Ajouté dans la version 3.11: Expressions in *tuple_slices* may be
starred. See **PEP 646**.

The subscript can also contain a starred expression. In this case, the
interpreter unpacks the result into a tuple, and passes this tuple to
"__getitem__()" or "__class_getitem__()":

   # continuing with the SubscriptionDemo instance defined above:
   >>> demo[*range(10)]
   subscripted with: (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

Starred expressions may be combined with comma-separated expressions
and slices:

   >>> demo['a', 'b', *range(3), 'c']
   subscripted with: ('a', 'b', 0, 1, 2, 'c')


6.3.2.4. Formal subscription grammar
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

   subscription:     primary '[' subscript ']'
   subscript:        single_subscript | tuple_subscript
   single_subscript: proper_slice | assignment_expression
   proper_slice:     [expression] ":" [expression] [ ":" [expression] ]
   tuple_subscript:  ','.(single_subscript | starred_expression)+ [',']

Recall that the "|" operator denotes ordered choice. Specifically, in
"subscript", if both alternatives would match, the first
("single_subscript") has priority.


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

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 :
   The code block for the function is executed, passing it the
   argument list.  The first thing the code block will do is bind the
   formal parameters to the arguments; this is described in section
   Définition de fonctions.  When the code block executes a "return"
   statement, this specifies the return value of the function call.
   If execution reaches the end of the code block without executing a
   "return" statement, the return value is "None".

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

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

The power operator has the same semantics as the built-in "pow()"
function, when called with two arguments: it yields its left argument
raised to the power of its right argument. Numeric arguments are first
converted to a common type, and the result is of that 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__()" and
"__rpow__()" methods.


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

The "*" (multiplication) operator yields the product of its arguments.
The arguments must either both be numbers, or one argument must be an
integer and the other must be a sequence. In the former case, the
numbers are converted to a common real type and then multiplied
together.  In the latter case, sequence repetition is performed; a
negative repetition factor yields an empty sequence.

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

Modifié dans la version 3.14: If only one operand is a complex number,
the other operand is converted to a floating-point number.

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

This operation can be customized using the special "__matmul__()" and
"__rmatmul__()" methods.

Ajouté dans la version 3.5.

The "/" (division) and "//" (floor division) operators yield the
quotient of their arguments.  The numeric arguments are first
converted to a common type. Division of integers yields a float, while
floor division of integers results in an integer; the result is that
of mathematical division with the 'floor' function applied to the
result.  Division by zero raises the "ZeroDivisionError" exception.

The division operation can be customized using the special
"__truediv__()" and "__rtruediv__()" methods. The floor division
operation can be customized using the special "__floordiv__()" and
"__rfloordiv__()" methods.

The "%" (modulo) operator yields the remainder from the division of
the first argument by the second.  The numeric arguments are first
converted to a common type. A zero right argument raises the
"ZeroDivisionError" exception.  The arguments may be floating-point
numbers, e.g., "3.14%0.7" equals "0.34" (since "3.14" equals "4*0.7 +
0.34".)  The modulo operator always yields a result with the same sign
as its second operand (or zero); the absolute value of the result is
strictly smaller than the absolute value of the second operand [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__()"
and "__rmod__()" methods.

The floor division operator, the modulo operator, and the "divmod()"
function are not defined for complex numbers.  Instead, convert to a
floating-point number using the "abs()" function if appropriate.

The "+" (addition) operator yields the sum of its arguments.  The
arguments must either both be numbers or both be sequences of the same
type.  In the former case, the numbers are converted to a common real
type and then added together. In the latter case, the sequences are
concatenated.

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

Modifié dans la version 3.14: If only one operand is a complex number,
the other operand is converted to a floating-point number.

The "-" (subtraction) operator yields the difference of its arguments.
The numeric arguments are first converted to a common real type.

This operation can be customized using the special "__sub__()" and
"__rsub__()" methods.

Modifié dans la version 3.14: If only one operand is a complex number,
the other operand is converted to a floating-point number.


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.

The left shift operation can be customized using the special
"__lshift__()" and "__rlshift__()" methods. The right shift operation
can be customized using the special "__rshift__()" and "__rrshift__()"
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.

Ajouté 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

A conditional expression (sometimes called a "ternary operator") is an
alternative to the if-else statement. As it is an expression, it
returns a value and can appear as a sub-expression.

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
==========================

   starred_expression:       "*" or_expr | expression
   flexible_expression:      assignment_expression | starred_expression
   flexible_expression_list: flexible_expression ("," flexible_expression)* [","]
   starred_expression_list:  starred_expression ("," starred_expression)* [","]
   expression_list:          expression ("," expression)* [","]
   yield_list:               expression_list | starred_expression "," [starred_expression_list]

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.

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

Ajouté dans la version 3.11: Any item in an expression list may be
starred. See **PEP 646**.

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[index]", "x[index:index]" "x(arguments...)", | Subscription (including slicing),     |
| "x.attribute"                                   | call, attribute reference             |
+-------------------------------------------------+---------------------------------------+
| "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é.
