Types natifs
************

Les sections suivantes décrivent les types standards intégrés à
l'interpréteur.

Les principaux types natifs sont les numériques, les séquences, les
dictionnaires, les classes, les instances et les exceptions.

Certaines classes de collection sont mutables. Les méthodes qui
ajoutent, retirent, ou réorganisent leurs éléments sur place, et qui
ne renvoient pas un élément spécifique, ne renvoient jamais l'instance
de la collection elle-même, mais "None".

Certaines opérations sont prises en charge par plusieurs types
d'objets ; en particulier, pratiquement tous les objets peuvent être
comparés en égalité, testés en véridicité (valeur booléenne) et
convertis en une chaîne de caractères (avec la fonction "repr()" ou la
fonction légèrement différente "str()"). Cette dernière est
implicitement utilisée quand un objet est affiché par la fonction
"print()".


Valeurs booléennes
==================

Tout objet peut être comparé à une valeur booléenne, typiquement dans
une condition "if" ou "while" ou comme opérande des opérations
booléennes ci-dessous.

By default, an object is considered true unless its class defines
either a "__bool__()" method that returns "False" or a "__len__()"
method that returns zero, when called with the object. [1] If one of
the methods raises an exception when called, the exception is
propagated and the object does not have a truth value (for example,
"NotImplemented"). Here are most of the built-in objects considered
false:

* les constantes définies comme étant fausses : "None" et "False" ;

* zéro de tout type numérique : "0", "0.0", "0j", "Decimal(0)",
  "Fraction(0, 1)"

* les chaînes et collections vides : "''", "()", "[]", "{}", "set()",
  "range(0)"

Les opérations et fonctions natives dont le résultat est booléen
renvoient toujours "0" ou "False" pour faux et "1" ou "True" pour
vrai, sauf indication contraire (exception importante : les opérations
booléennes "or" et "and" renvoient toujours l'une de leurs opérandes).


Opérations booléennes — "and", "or", "not"
==========================================

Ce sont les opérations booléennes, classées par priorité ascendante :

+---------------+-----------------------------------+---------+
| Opération     | Résultat                          | Notes   |
|===============|===================================|=========|
| "x or y"      | si *x* est vrai, alors *x*, sinon | (1)     |
|               | *y*                               |         |
+---------------+-----------------------------------+---------+
| "x and y"     | si *x* est faux, alors *x*, sinon | (2)     |
|               | *y*                               |         |
+---------------+-----------------------------------+---------+
| "not x"       | si *x* est faux, alors "True",    | (3)     |
|               | sinon "False"                     |         |
+---------------+-----------------------------------+---------+

Notes :

1. C'est un opérateur court-circuit : il n'évalue le deuxième argument
   que si le premier est faux.

2. C'est un opérateur court-circuit : il n'évalue le deuxième argument
   que si le premier est vrai.

3. "not" a une priorité inférieure à celle des opérateurs non-
   booléens, donc "not a == b" est interprété comme "not (a == b)" et
   "a == not b" est une erreur de syntaxe.


Comparaisons
============

Il y a huit opérations de comparaison en Python. Elles ont toutes la
même priorité (qui est supérieure à celle des opérations booléennes).
Les comparaisons peuvent être enchaînées arbitrairement ; par exemple,
"x < y <= z" est équivalent à "x < y and y <= z", sauf que *y* n'est
évalué qu'une seule fois (mais dans les deux cas *z* n'est pas évalué
du tout quand "x < y" est faux).

Ce tableau résume les opérations de comparaison :

+--------------+---------------------------+
| Opération    | Signification             |
|==============|===========================|
| "<"          | strictement inférieur     |
+--------------+---------------------------+
| "<="         | inférieur ou égal         |
+--------------+---------------------------+
| ">"          | strictement supérieur     |
+--------------+---------------------------+
| ">="         | supérieur ou égal         |
+--------------+---------------------------+
| "=="         | égal                      |
+--------------+---------------------------+
| "!="         | différent                 |
+--------------+---------------------------+
| "is"         | identité d'objet          |
+--------------+---------------------------+
| "is not"     | contraire de l'identité   |
|              | d'objet                   |
+--------------+---------------------------+

Unless stated otherwise, objects of different types never compare
equal. The "==" operator is always defined but for some object types
(for example, class objects) is equivalent to "is". The "<", "<=", ">"
and ">=" operators are only defined where they make sense; for
example, they raise a "TypeError" exception when one of the arguments
is a complex number.

Des instances différentes d'une classe sont normalement considérées
différentes à moins que la classe ne définisse la méthode "__eq__()".

Les instances d'une classe ne peuvent pas être ordonnées par rapport à
d'autres instances de la même classe, ou d'autres types d'objets, à
moins que la classe ne définisse suffisamment de méthodes parmi
"__lt__()", "__le__()", "__gt__()" et "__ge__()" (en général,
"__lt__()" et "__eq__()" sont suffisantes, si vous voulez les
significations classiques des opérateurs de comparaison).

Le comportement des opérateurs "is" et "is not" ne peut pas être
personnalisé ; aussi ils peuvent être appliqués à deux objets
quelconques et ne lèvent jamais d'exception.

Deux autres opérations avec la même priorité syntaxique, "in" et "not
in", sont pris en charge par les types *iterable* ou qui implémentent
la méthode "__contains__()".


Types numériques — "int", "float", "complex"
============================================

Il existe trois types numériques distincts : les entiers (*integers*),
les nombres flottants (*floating point numbers*) et les nombres
complexes (*complex numbers*). En outre, les booléens sont un sous-
type des entiers. Les entiers ont une précision illimitée. Les nombres
à virgule flottante sont généralement implémentés en utilisant des
double en C ; des informations sur la précision et la représentation
interne des nombres à virgule flottante pour la machine sur laquelle
le programme est en cours d'exécution sont disponibles dans
"sys.float_info". Les nombres complexes ont une partie réelle et une
partie imaginaire, qui sont chacune des nombres à virgule flottante.
Pour extraire ces parties d'un nombre complexe *z*, utilisez "z.real"
et "z.imag". (La bibliothèque standard comprend les types numériques
additionnels "fractions.Fraction" pour les rationnels et
"decimal.Decimal" pour les nombres à virgule flottante avec une
précision définissable par l'utilisateur.)

Les nombres sont créés par des littéraux numériques ou sont le
résultat de fonctions natives ou d'opérateurs. Les entiers littéraux
basiques (y compris leur forme hexadécimale, octale et binaire)
donnent des entiers. Les nombres littéraux contenant un point décimal
(NdT : notation anglo-saxonne de la virgule) ou un exposant donnent
des nombres à virgule flottante. Suffixer "'j'" ou "'J'" à un nombre
littéral donne un nombre imaginaire (un nombre complexe avec une
partie réelle nulle) que vous pouvez ajouter à un nombre (entier ou à
virgule flottante) pour obtenir un nombre complexe avec une partie
réelle et une partie imaginaire.

Les constructeurs "int()", "float()" et "complex()" peuvent être
utilisés pour produire des nombres d'un type numérique spécifique.

Python fully supports mixed arithmetic: when a binary arithmetic
operator has operands of different built-in numeric types, the operand
with the "narrower" type is widened to that of the other:

* If both arguments are complex numbers, no conversion is performed;

* if either argument is a complex or a floating-point number, the
  other is converted to a floating-point number;

* otherwise, both must be integers and no conversion is necessary.

Arithmetic with complex and real operands is defined by the usual
mathematical formula, for example:

   x + complex(u, v) = complex(x + u, v)
   x * complex(u, v) = complex(x * u, x * v)

A comparison between numbers of different types behaves as though the
exact values of those numbers were being compared. [2]

Tous les types numériques (sauf complexe) gèrent les opérations
suivantes (pour les priorités des opérations, voir Priorités des
opérateurs) :

+-----------------------+-----------------------------------+-----------+----------------------+
| Opération             | Résultat                          | Notes     | Documentation        |
|                       |                                   |           | complète             |
|=======================|===================================|===========|======================|
| "x + y"               | somme de *x* et *y*               |           |                      |
+-----------------------+-----------------------------------+-----------+----------------------+
| "x - y"               | différence de *x* et *y*          |           |                      |
+-----------------------+-----------------------------------+-----------+----------------------+
| "x * y"               | produit de *x* et *y*             |           |                      |
+-----------------------+-----------------------------------+-----------+----------------------+
| "x / y"               | quotient de *x* et *y*            |           |                      |
+-----------------------+-----------------------------------+-----------+----------------------+
| "x // y"              | quotient entier de *x* et *y*     | (1)(2)    |                      |
+-----------------------+-----------------------------------+-----------+----------------------+
| "x % y"               | reste de "x / y"                  | (2)       |                      |
+-----------------------+-----------------------------------+-----------+----------------------+
| "-x"                  | négatif de *x*                    |           |                      |
+-----------------------+-----------------------------------+-----------+----------------------+
| "+x"                  | *x* inchangé                      |           |                      |
+-----------------------+-----------------------------------+-----------+----------------------+
| "abs(x)"              | valeur absolue de *x*             |           | "abs()"              |
+-----------------------+-----------------------------------+-----------+----------------------+
| "int(x)"              | *x* converti en nombre entier     | (3)(6)    | "int()"              |
+-----------------------+-----------------------------------+-----------+----------------------+
| "float(x)"            | *x* converti en nombre à virgule  | (4)(6)    | "float()"            |
|                       | flottante                         |           |                      |
+-----------------------+-----------------------------------+-----------+----------------------+
| "complex(re, im)"     | un nombre complexe avec *re* pour | (6)       | "complex()"          |
|                       | partie réelle et *im* pour partie |           |                      |
|                       | imaginaire. *im* vaut zéro par    |           |                      |
|                       | défaut.                           |           |                      |
+-----------------------+-----------------------------------+-----------+----------------------+
| "c.conjugate()"       | conjugué du nombre complexe *c*   |           |                      |
+-----------------------+-----------------------------------+-----------+----------------------+
| "divmod(x, y)"        | la paire "(x // y, x % y)"        | (2)       | "divmod()"           |
+-----------------------+-----------------------------------+-----------+----------------------+
| "pow(x, y)"           | *x* à la puissance *y*            | (5)       | "pow()"              |
+-----------------------+-----------------------------------+-----------+----------------------+
| "x ** y"              | *x* à la puissance *y*            | (5)       |                      |
+-----------------------+-----------------------------------+-----------+----------------------+

Notes :

1. Également appelé division entière. Pour les opérandes de type
   "int", la valeur résultante est de type "int". Pour les opérandes
   de type "float",la valeur résultante est de type "float". En
   général, la valeur résultante est strictement entière,  bien que le
   type du résultat ne soit pas nécessairement "int". Le résultat est
   toujours arrondi vers moins l'infini : "1//2" vaut "0", "(-1)//2"
   vaut "-1", "1//(-2)" vaut "-1", et "(-1)//(-2)" vaut "0".

2. Pas pour les nombres complexes. Convertissez-les plutôt en nombres
   flottants à l'aide de "abs()" si c'est approprié.

3. La conversion de "float" en "int" tronque la partie fractionnaire.
   Voir les fonctions "math.floor()" et "math.ceil()" pour d'autres
   conversions.

4. *float* accepte aussi les chaînes *nan* et *inf* avec un préfixe
   optionnel "+" ou "-" pour *Not a Number* (*NaN*) et les infinis
   positif ou négatif.

5. Python définit "pow(0, 0)" et "0 ** 0" valant "1", puisque c'est
   courant pour les langages de programmation, et logique.

6. Les littéraux numériques acceptés comprennent les chiffres "0" à
   "9" ou tout équivalent Unicode (caractères avec la propriété "Nd").

   See the Unicode Standard for a complete list of code points with
   the "Nd" property.

Tous types "numbers.Real" ("int" et "float") comprennent également les
opérations suivantes :

+----------------------+-----------------------------------------------+
| Opération            | Résultat                                      |
|======================|===============================================|
| "math.trunc(x)"      | *x* tronqué à l'"Integral"                    |
+----------------------+-----------------------------------------------+
| "round(x[, n])"      | *x* arrondi à *n* chiffres, arrondissant la   |
|                      | moitié au pair. Si *n* est omis, la valeur    |
|                      | par défaut est 0.                             |
+----------------------+-----------------------------------------------+
| "math.floor(x)"      | le plus grand "Integral" ≤ *x*                |
+----------------------+-----------------------------------------------+
| "math.ceil(x)"       | le plus petit "Integral" ≥ *x*                |
+----------------------+-----------------------------------------------+

Pour d'autres opérations numériques voir les modules "math" et
"cmath".


Opérations sur les bits des nombres entiers
-------------------------------------------

Les opérations bit à bit n'ont de sens que pour les entiers relatifs.
Le résultat d'une opération bit à bit est calculé comme si elle était
effectuée en complément à deux avec un nombre infini de bits de signe.

Les priorités de toutes les opérations bit à bit à deux opérandes sont
inférieures à celles des opérations numériques et plus élevées que les
comparaisons ; l'opération unaire "~" a la même priorité que les
autres opérations numériques unaires ("+" et "-").

Ce tableau répertorie les opérations binaires triées par priorité
ascendante :

+--------------+----------------------------------+------------+
| Opération    | Résultat                         | Notes      |
|==============|==================================|============|
| "x | y"      | *OU* bit à bit de *x* et *y*     | (4)        |
+--------------+----------------------------------+------------+
| "x ^ y"      | *OU exclusif* bit à bit de *x*   | (4)        |
|              | et *y*                           |            |
+--------------+----------------------------------+------------+
| "x & y"      | *ET* bit à bit de *x* et *y*     | (4)        |
+--------------+----------------------------------+------------+
| "x << n"     | *x* décalé vers la gauche de *n* | (1)(2)     |
|              | bits                             |            |
+--------------+----------------------------------+------------+
| "x >> n"     | *x* décalé vers la droite de *n* | (1)(3)     |
|              | bits                             |            |
+--------------+----------------------------------+------------+
| "~x"         | les bits de *x*, inversés        |            |
+--------------+----------------------------------+------------+

Notes :

1. Des valeurs de décalage négatives sont illégales et provoquent une
   exception "ValueError".

2. Un décalage à gauche de *n* bits est équivalent à la multiplication
   par "pow(2, n)".

3. Un décalage à droite de *n* les bits est équivalent à la division
   par "pow(2, n)".

4. Effectuer ces calculs avec au moins un bit d'extension de signe
   supplémentaire dans une représentation finie du complément à deux
   éléments (une largeur de bit fonctionnelle de "1 +
   max(x.bit_length(), y.bit_length()" ou plus) est suffisante pour
   obtenir le même résultat que s'il y avait un nombre infini de bits
   de signe.


Méthodes supplémentaires sur les entiers
----------------------------------------

Le type *int* implémente la *classe mère abstraite*
"numbers.Integral". Il fournit aussi quelques autres méthodes :

int.bit_length()

   Renvoie le nombre de bits nécessaires pour représenter un nombre
   entier en binaire, à l'exclusion du signe et des zéros non
   significatifs :

      >>> n = -37
      >>> bin(n)
      '-0b100101'
      >>> n.bit_length()
      6

   Plus précisément, si "x" est différent de zéro, "x.bit_length()"
   est le nombre entier positif unique, "k" tel que "2**(k-1) <=
   abs(x) < 2**k". Équivalemment, quand "abs(x)" est assez petit pour
   avoir un logarithme correctement arrondi, "k = 1 + int(log(abs(x),
   2))". Si "x" est nul, alors "x.bit_length()" donne "0".

   Équivalent à :

      def bit_length(self):
          s = bin(self)       # binary representation:  bin(-37) --> '-0b100101'
          s = s.lstrip('-0b') # remove leading zeros and minus sign
          return len(s)       # len('100101') --> 6

   Ajouté dans la version 3.1.

int.bit_count()

   Renvoie le nombre de 1 dans la représentation binaire de la valeur
   absolue de l'entier. On la connait également sous le nom de
   dénombrement de la population. Par exemple :

      >>> n = 19
      >>> bin(n)
      '0b10011'
      >>> n.bit_count()
      3
      >>> (-n).bit_count()
      3

   Équivalent à :

      def bit_count(self):
          return bin(self).count("1")

   Ajouté dans la version 3.10.

int.to_bytes(length=1, byteorder='big', *, signed=False)

   Renvoie un tableau d'octets représentant un nombre entier.

   >>> (1024).to_bytes(2, byteorder='big')
   b'\x04\x00'
   >>> (1024).to_bytes(10, byteorder='big')
   b'\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00'
   >>> (-1024).to_bytes(10, byteorder='big', signed=True)
   b'\xff\xff\xff\xff\xff\xff\xff\xff\xfc\x00'
   >>> x = 1000
   >>> x.to_bytes((x.bit_length() + 7) // 8, byteorder='little')
   b'\xe8\x03'

   L'entier est représenté en utilisant *length* octets, dont la
   valeur par défaut est 1. Une exception "OverflowError" est levée
   s'il n'est pas possible de représenter l'entier avec le nombre
   donné d'octets.

   L'argument *byteorder* détermine l'ordre des octets utilisé pour
   représenter le nombre entier, la valeur par défaut étant ""big"".
   Si *byteorder* est ""big"", l'octet le plus significatif est au
   début du tableau d'octets. Si *byteorder* est ""little"", l'octet
   le plus significatif est à la fin du tableau d'octets.

   L'argument *signed* détermine si le complément à deux est utilisé
   pour représenter le nombre entier. Si *signed* est "False" et qu'un
   entier négatif est donné, une exception "OverflowError" est levée.
   La valeur par défaut pour *signed* est "False".

   Les valeurs par défaut peuvent être utilisées pour transformer
   facilement un entier en un objet à un seul octet :

      >>> (65).to_bytes()
      b'A'

   Cependant, lorsque vous utilisez les arguments par défaut,
   n'essayez pas de convertir une valeur supérieure à 255 ou vous
   lèverez une "OverflowError" :

   Équivalent à :

      def to_bytes(n, length=1, byteorder='big', signed=False):
          if byteorder == 'little':
              order = range(length)
          elif byteorder == 'big':
              order = reversed(range(length))
          else:
              raise ValueError("byteorder must be either 'little' or 'big'")

          return bytes((n >> i*8) & 0xff for i in order)

   Ajouté dans la version 3.2.

   Modifié dans la version 3.11: ajout de valeurs par défaut pour les
   arguments "length" et "byteorder".

classmethod int.from_bytes(bytes, byteorder='big', *, signed=False)

   Renvoie le nombre entier représenté par le tableau d'octets fourni.

   >>> int.from_bytes(b'\x00\x10', byteorder='big')
   16
   >>> int.from_bytes(b'\x00\x10', byteorder='little')
   4096
   >>> int.from_bytes(b'\xfc\x00', byteorder='big', signed=True)
   -1024
   >>> int.from_bytes(b'\xfc\x00', byteorder='big', signed=False)
   64512
   >>> int.from_bytes([255, 0, 0], byteorder='big')
   16711680

   L'argument *bytes* doit être soit un *objet octet-compatible*, soit
   un itérable produisant des *bytes*.

   L'argument *byteorder* détermine l'ordre des octets utilisé pour
   représenter le nombre entier, la valeur par défaut étant ""big"".
   Si *byteorder* est ""big"", l'octet le plus significatif est au
   début du tableau d'octets. Si *byteorder* est ""little"", l'octet
   le plus significatif est à la fin du tableau d'octets. Pour
   demander l'ordre natif des octets du système hôte, donnez
   "sys.byteorder" comme *byteorder*.

   L'argument *signed* indique si le complément à deux est utilisé
   pour représenter le nombre entier.

   Équivalent à :

      def from_bytes(bytes, byteorder='big', signed=False):
          if byteorder == 'little':
              little_ordered = list(bytes)
          elif byteorder == 'big':
              little_ordered = list(reversed(bytes))
          else:
              raise ValueError("byteorder must be either 'little' or 'big'")

          n = sum(b << i*8 for i, b in enumerate(little_ordered))
          if signed and little_ordered and (little_ordered[-1] & 0x80):
              n -= 1 << 8*len(little_ordered)

          return n

   Ajouté dans la version 3.2.

   Modifié dans la version 3.11: ajout de la valeur par défaut pour
   l'argument "byteorder".

int.as_integer_ratio()

   Return a pair of integers whose ratio is equal to the original
   integer and has a positive denominator.  The integer ratio of
   integers (whole numbers) is always the integer as the numerator and
   "1" as the denominator.

   Ajouté dans la version 3.8.

int.is_integer()

   Returns "True". Exists for duck type compatibility with
   "float.is_integer()".

   Ajouté dans la version 3.12.


Méthodes supplémentaires sur les nombres à virgule flottante
------------------------------------------------------------

Le type *float* implémente la *classe mère abstraite* "numbers.Real"
et a également les méthodes suivantes.

classmethod float.from_number(x)

   Class method to return a floating-point number constructed from a
   number *x*.

   If the argument is an integer or a floating-point number, a
   floating-point number with the same value (within Python's
   floating-point precision) is returned.  If the argument is outside
   the range of a Python float, an "OverflowError" will be raised.

   For a general Python object "x", "float.from_number(x)" delegates
   to "x.__float__()". If "__float__()" is not defined then it falls
   back to "__index__()".

   Ajouté dans la version 3.14.

float.as_integer_ratio()

   Return a pair of integers whose ratio is exactly equal to the
   original float. The ratio is in lowest terms and has a positive
   denominator.  Raises "OverflowError" on infinities and a
   "ValueError" on NaNs.

float.is_integer()

   Renvoie "True" si l'instance de *float* est finie avec une valeur
   entière, et "False" autrement :

      >>> (-2.0).is_integer()
      True
      >>> (3.2).is_integer()
      False

Deux méthodes prennent en charge la conversion vers et à partir de
chaînes hexadécimales. Étant donné que les *float* de Python sont
stockés en interne sous forme de nombres binaires, la conversion d'un
*float* depuis ou vers une chaine décimale implique généralement une
petite erreur d'arrondi. En revanche, les chaînes hexadécimales
permettent de représenter exactement les nombres à virgule flottante.
Cela peut être utile lors du débogage, et dans un travail numérique.

float.hex()

   Renvoie une représentation d'un nombre à virgule flottante sous
   forme de chaîne hexadécimale. Pour les nombres à virgule flottante
   finis, cette représentation comprendra toujours un préfixe "0x", un
   suffixe "p" et un exposant.

classmethod float.fromhex(s)

   Méthode de classe pour obtenir le *float* représenté par une chaîne
   de caractères hexadécimale *s*. La chaîne *s* peut contenir des
   espaces avant et après le nombre.

Notez que "float.hex()" est une méthode d'instance, alors que
"float.fromhex()" est une méthode de classe.

Une chaîne hexadécimale prend la forme :

   [sign] ['0x'] integer ['.' fraction] ['p' exponent]

où "sign" peut être soit "+" soit "-", "integer" et "fraction" sont
des chaînes de chiffres hexadécimaux, et "exponent" est un entier
décimal facultativement signé. La casse n'est pas significative, et il
doit y avoir au moins un chiffre hexadécimal soit dans le nombre
entier soit dans la fraction. Cette syntaxe est similaire à la syntaxe
spécifiée dans la section 6.4.4.2 de la norme C99, et est aussi la
syntaxe utilisée à partir de Java 1.5. En particulier, la sortie de
"float.hex()" est utilisable comme valeur hexadécimale à virgule
flottante littérale en C ou Java, et des chaînes hexadécimales
produites en C via un format "%a" ou Java via "Double.toHexString"
sont acceptées par "float.fromhex()".

Notez que l'exposant est écrit en décimal plutôt qu'en hexadécimal, et
qu'il donne la puissance de 2 par lequel multiplier le coefficient.
Par exemple, la chaîne hexadécimale "0x3.a7p10" représente le nombre à
virgule flottante "(3 + 10./16 + 7./16**2) *2.0**10", ou "3740.0" :

   >>> float.fromhex('0x3.a7p10')
   3740.0

L'application de la conversion inverse à "3740.0" donne une chaîne
hexadécimale différente représentant le même nombre :

   >>> float.hex(3740.0)
   '0x1.d380000000000p+11'


Additional Methods on Complex
-----------------------------

The "complex" type implements the "numbers.Complex" *abstract base
class*. "complex" also has the following additional methods.

classmethod complex.from_number(x)

   Class method to convert a number to a complex number.

   For a general Python object "x", "complex.from_number(x)" delegates
   to "x.__complex__()".  If "__complex__()" is not defined then it
   falls back to "__float__()".  If "__float__()" is not defined then
   it falls back to "__index__()".

   Ajouté dans la version 3.14.


Hachage des types numériques
----------------------------

For numbers "x" and "y", possibly of different types, it's a
requirement that "hash(x) == hash(y)" whenever "x == y" (see the
"__hash__()" method documentation for more details).  For ease of
implementation and efficiency across a variety of numeric types
(including "int", "float", "decimal.Decimal" and "fractions.Fraction")
Python's hash for numeric types is based on a single mathematical
function that's defined for any rational number, and hence applies to
all instances of "int" and "fractions.Fraction", and all finite
instances of "float" and "decimal.Decimal".  Essentially, this
function is given by reduction modulo "P" for a fixed prime "P".  The
value of "P" is made available to Python as the "modulus" attribute of
"sys.hash_info".

actuellement, le premier utilisé est "P = 2 ** 31 - 1" sur des
machines dont les *longs* en C sont de 32 bits "P = 2 ** 61 - 1" sur
des machines dont les *longs* en C font 64 bits.

Voici les règles en détail :

* Si "x = m / n" est un nombre rationnel non négatif et "n" n'est pas
  divisible par "P", définir "hash(x)" comme "m * invmod(n, P) % P",
  où "invmod(n, P)" donne l'inverse de "n" modulo "P".

* Si "x = m / n" est un nombre rationnel non négatif et "n" est
  divisible par "P" (mais "m" ne l'est pas), alors "n" n'a pas de
  modulo inverse "P" et la règle ci-dessus n'est pas applicable ; dans
  ce cas définir "hash(x)" comme étant la valeur de la constante
  "sys.hash_info.inf".

* Si "x = m / n" est un nombre rationnel négatif définir "hash(x)"
  comme "-hash(-x)". Si le résultat est "-1", le remplacer par "-2".

* Les valeurs particulières "sys.hash_info.inf" et
  "-sys.hash_info.inf" sont utilisées comme valeurs de hachage pour
  l'infini positif et l'infini négatif (respectivement).

* Pour un nombre "complexe" "z", les valeurs de hachage des parties
  réelles et imaginaires sont combinées en calculant "hash(z.real) +
  sys.hash_info.imag * hash(z.imag)", réduit au modulo
  "2**sys.hash_info.width" de sorte qu'il se trouve dans
  "range(-2**(sys.hash_info.width - 1), 2**(sys.hash_info.width -
  1))". Encore une fois, si le résultat est "-1", il est remplacé par
  "-2".

Afin de clarifier les règles ci-dessus, voici quelques exemples de
code Python, équivalent à la fonction de hachage native, pour calculer
le hachage d'un nombre rationnel,  d'un "float", ou d'un "complex" :

   import sys, math

   def hash_fraction(m, n):
       """Compute the hash of a rational number m / n.

       Assumes m and n are integers, with n positive.
       Equivalent to hash(fractions.Fraction(m, n)).

       """
       P = sys.hash_info.modulus
       # Remove common factors of P.  (Unnecessary if m and n already coprime.)
       while m % P == n % P == 0:
           m, n = m // P, n // P

       if n % P == 0:
           hash_value = sys.hash_info.inf
       else:
           # Fermat's Little Theorem: pow(n, P-1, P) is 1, so
           # pow(n, P-2, P) gives the inverse of n modulo P.
           hash_value = (abs(m) % P) * pow(n, P - 2, P) % P
       if m < 0:
           hash_value = -hash_value
       if hash_value == -1:
           hash_value = -2
       return hash_value

   def hash_float(x):
       """Compute the hash of a float x."""

       if math.isnan(x):
           return object.__hash__(x)
       elif math.isinf(x):
           return sys.hash_info.inf if x > 0 else -sys.hash_info.inf
       else:
           return hash_fraction(*x.as_integer_ratio())

   def hash_complex(z):
       """Compute the hash of a complex number z."""

       hash_value = hash_float(z.real) + sys.hash_info.imag * hash_float(z.imag)
       # do a signed reduction modulo 2**sys.hash_info.width
       M = 2**(sys.hash_info.width - 1)
       hash_value = (hash_value & (M - 1)) - (hash_value & M)
       if hash_value == -1:
           hash_value = -2
       return hash_value


Boolean Type - "bool"
=====================

Booleans represent truth values. The "bool" type has exactly two
constant instances: "True" and "False".

The built-in function "bool()"  converts any value to a boolean, if
the value can be interpreted as a truth value (see section Valeurs
booléennes above).

For logical operations, use the boolean operators "and", "or" and
"not". When applying the bitwise operators "&", "|", "^" to two
booleans, they return a bool equivalent to the logical operations
"and", "or", "xor". However, the logical operators "and", "or" and
"!=" should be preferred over "&", "|" and "^".

Obsolète depuis la version 3.12: The use of the bitwise inversion
operator "~" is deprecated and will raise an error in Python 3.16.

"bool" is a subclass of "int" (see Types numériques — int, float,
complex). In many numeric contexts, "False" and "True" behave like the
integers 0 and 1, respectively. However, relying on this is
discouraged; explicitly convert using "int()" instead.


Les types itérateurs
====================

Python gère un concept d'itération sur les conteneurs. Il l'implémente
en utilisant deux méthodes distinctes qui permettent aux classes
définies par l'utilisateur de devenir itérables. Les séquences,
décrites plus bas en détail, savent toujours gérer les méthodes
d'itération.

Une méthode doit être définie afin que les objets conteneurs prennent
en charge *l’itération* :

container.__iter__()

   Renvoie un objet *itérateur*. L'objet doit implémenter le protocole
   d'itération décrit ci-dessous. Si un conteneur prend en charge
   différents types d'itération, d'autres méthodes peuvent être
   fournies pour obtenir spécifiquement les itérateurs pour ces types
   d'itération. (Exemple d'un objet gérant plusieurs formes
   d'itération : une structure d'arbre pouvant être parcourue en
   largeur ou en profondeur.) Cette méthode correspond à l'attribut
   "tp_iter" de la structure du type des objets Python dans l'API
   Python/C.

Les itérateurs eux-mêmes doivent implémenter les deux méthodes
suivantes, qui forment ensemble le *protocole d'itération* :

iterator.__iter__()

   Renvoie *l’objet itérateur* lui-même. C'est nécessaire pour
   permettre à la fois à des conteneurs et des itérateurs d'être
   utilisés avec les instructions "for" et "in". Cette méthode
   correspond à l'attribut "tp_iter" de la structure des types des
   objets Python dans l'API Python/C.

iterator.__next__()

   Renvoie l'élément suivant de l’*itérateur*. S'il n'y a pas d'autres
   éléments, une exception "StopIteration" est levée. Cette méthode
   correspond à l'attribut "tp_iternext" de la structure du type des
   objets Python dans l'API Python/C.

Python définit plusieurs objets itérateurs pour itérer sur les types
standards ou spécifiques de séquence, de  dictionnaires et d'autres
formes plus spécialisées. Les types spécifiques ne sont  pas
importants au-delà de leur implémentation du protocole d'itération.

Dès que la méthode "__next__()" lève une  exception "StopIteration",
elle doit continuer à le faire lors des appels ultérieurs. Les
implémentations qui ne respectent pas cette propriété sont considérées
cassées.


Types générateurs
-----------------

Python's *generator*s provide a convenient way to implement the
iterator protocol.  If a container object's "__iter__()" method is
implemented as a generator, it will automatically return an iterator
object (technically, a generator object) supplying the "__iter__()"
and "__next__()" methods. More information about generators can be
found in the documentation for the yield expression.


Types séquentiels — "list", "tuple", "range"
============================================

Il existe trois types séquentiels élémentaires : les listes (objets
*list*), *n*-uplets (objets *tuple*) et les intervalles (objets
*range*). D'autres types séquentiels spécifiques au traitement de
données binaires et chaînes de caractères sont décrits dans des
sections dédiées.


Opérations communes sur les séquences
-------------------------------------

Les opérations dans le tableau ci-dessous sont prises en charge par la
plupart des types séquentiels, variables et immuables. La classe mère
abstraite "collections.abc.Sequence" est fournie pour aider à
implémenter correctement ces opérations sur les types séquentiels
personnalisés.

Ce tableau répertorie les opérations sur les séquences  triées par
priorité ascendante. Dans le tableau, *s* et *t* sont des séquences du
même type, *n*, *i*, *j* et *k* sont des nombres entiers et *x* est un
objet arbitraire qui répond à toutes les restrictions de type et de
valeur imposée par *s*.

Les opérations "in" et "not in" ont les mêmes priorités que les
opérations de comparaison. Les opérations "+" (concaténation) et "*"
(répétition) ont la même priorité que les opérations numériques
correspondantes [3].

+----------------------------+----------------------------------+------------+
| Opération                  | Résultat                         | Notes      |
|============================|==================================|============|
| "x in s"                   | "True" si un élément de *s* est  | (1)        |
|                            | égal à *x*, sinon "False"        |            |
+----------------------------+----------------------------------+------------+
| "x not in s"               | "False" si un élément de *s* est | (1)        |
|                            | égal à *x*, sinon "True"         |            |
+----------------------------+----------------------------------+------------+
| "s + t"                    | la concaténation de *s* et *t*   | (6)(7)     |
+----------------------------+----------------------------------+------------+
| "s * n" ou "n * s"         | équivalent à ajouter *s* *n*     | (2)(7)     |
|                            | fois à lui-même                  |            |
+----------------------------+----------------------------------+------------+
| "s[i]"                     | *i*^e élément de *s* en          | (3)(8)     |
|                            | commençant par 0                 |            |
+----------------------------+----------------------------------+------------+
| "s[i:j]"                   | tranche (*slice*) de *s* de *i*  | (3)(4)     |
|                            | à *j*                            |            |
+----------------------------+----------------------------------+------------+
| "s[i:j:k]"                 | tranche (*slice*) de *s* de *i*  | (3)(5)     |
|                            | à *j* avec un pas de *k*         |            |
+----------------------------+----------------------------------+------------+
| "len(s)"                   | longueur de *s*                  |            |
+----------------------------+----------------------------------+------------+
| "min(s)"                   | plus petit élément de *s*        |            |
+----------------------------+----------------------------------+------------+
| "max(s)"                   | plus grand élément de *s*        |            |
+----------------------------+----------------------------------+------------+

Les séquences du même type gèrent également la comparaison. En
particulier, les *n*-uplets et les listes sont comparés
lexicographiquement en comparant les éléments correspondants. Cela
signifie que, pour que deux séquences soit égales, les éléments les
constituant doivent être égaux deux à deux et les deux séquences
doivent être du même type et de la même longueur. (Pour plus de
détails voir Comparaisons dans la référence du langage.)

Les itérateurs avant et arrière sur des séquences modifiables accèdent
aux valeurs à l'aide d'un indice. Cet indice continue à avancer (ou à
reculer) même si la séquence sous-jacente est modifiée. L'itérateur ne
se termine que lorsqu'une "IndexError" ou une "StopIteration" est
rencontrée (ou lorsque l'indice tombe en dessous de zéro).

Notes :

1. Bien que les opérations "in" et "not in" ne soient généralement
   utilisées que pour les tests d'appartenance simple, certaines
   séquences spécialisées (telles que "str", "bytes" et "bytearray")
   les utilisent aussi pour tester l'existence de sous-séquences :

      >>> "gg" in "eggs"
      True

2. Les valeurs de *n* plus petites que "0" sont traitées comme "0" (ce
   qui donne une séquence vide du même type que *s*). Notez que les
   éléments de *s* ne sont pas copiés ; ils sont référencés plusieurs
   fois. Cela hante souvent de nouveaux développeurs Python,
   typiquement :

      >>> lists = [[]] * 3
      >>> lists
      [[], [], []]
      >>> lists[0].append(3)
      >>> lists
      [[3], [3], [3]]

   Ce qui est arrivé est que "[[]]" est une liste à un élément
   contenant une liste vide, de sorte que les trois éléments de "[[]]
   * 3" sont des références à cette seule liste vide. Modifier l'un
   des éléments de "lists" modifie cette liste unique. Vous pouvez
   créer une liste des différentes listes de cette façon :

      >>> lists = [[] for i in range(3)]
      >>> lists[0].append(3)
      >>> lists[1].append(5)
      >>> lists[2].append(7)
      >>> lists
      [[3], [5], [7]]

   De plus amples explications sont disponibles dans la FAQ à la
   question Comment créer une liste à plusieurs dimensions ?.

3. Si *i* ou *j* sont négatifs, l'indice est relatif à la fin de la
   séquence *s* : "len(s) + i" ou "len(s) + j" est substitué. Mais
   notez que "-0" est toujours "0".

4. The slice of *s* from *i* to *j* is defined as the sequence of
   items with index *k* such that "i <= k < j".

   * If *i* is omitted or "None", use "0".

   * If *j* is omitted or "None", use "len(s)".

   * If *i* or *j* is less than "-len(s)", use "0".

   * If *i* or *j* is greater than "len(s)", use "len(s)".

   * If *i* is greater than or equal to *j*, the slice is empty.

5. La tranche de *s* de *i* à *j* avec un pas de *k* est définie comme
   la séquence d'éléments d'indices "x = i + n*k" tels que "0 <= n <
   (j-i)/k". En d'autres termes, les indices sont "i", "i+k", "i+2*k",
   "i+3*k" et ainsi de suite, en arrêtant lorsque *j* est atteint
   (mais jamais inclus). Si *k* est positif, *i* et *j* sont réduits,
   s'ils sont plus grands, à "len(s)". Si *k* est négatif, *i* et *j*
   sont réduits à "len(s) - 1" s'ils sont plus grands. Si *i* ou *j*
   sont omis ou sont "None", ils deviennent des valeurs « limites »
   (la limite haute ou basse dépend du signe de *k*). Notez que *k* ne
   peut pas valoir zéro. Si *k* est "None", il est traité comme "1".

6. Concaténer des séquences immuables donne toujours un nouvel objet.
   Cela signifie que la construction d'une séquence par concaténations
   répétées aura une durée d'exécution quadratique par rapport à la
   longueur de la séquence totale. Pour obtenir un temps d'exécution
   linéaire, vous devez utiliser l'une des alternatives suivantes :

   * si vous concaténez des "str", vous pouvez construire une liste
     puis utiliser "str.join()" à la fin, ou bien écrire dans une
     instance de "io.StringIO" et récupérer sa valeur lorsque vous
     avez terminé ;

   * si vous concaténez des "bytes", vous pouvez aussi utiliser
     "bytes.join()" ou "io.BytesIO", ou vous pouvez faire les
     concaténations sur place avec un objet "bytearray". Les objets
     "bytearray" sont mutables et ont un mécanisme de sur-allocation
     efficace ;

   * si vous concaténez des "n-uplets", utilisez plutôt *extend* sur
     une "list" ;

   * pour les autres types, cherchez dans la documentation de la
     classe concernée.

7. Certains types séquentiels (tels que "range") ne gèrent que des
   séquences qui suivent des modèles spécifiques, et donc ne prennent
   pas en charge la concaténation ou la répétition.

8. An "IndexError" is raised if *i* is outside the sequence range.

-[ Sequence Methods ]-

Sequence types also support the following methods:

sequence.count(value, /)

   Return the total number of occurrences of *value* in *sequence*.

sequence.index(value[, start[, stop])

   Return the index of the first occurrence of *value* in *sequence*.

   Raises "ValueError" if *value* is not found in *sequence*.

   The *start* or *stop* arguments allow for efficient searching of
   subsections of the sequence, beginning at *start* and ending at
   *stop*. This is roughly equivalent to "start +
   sequence[start:stop].index(value)", only without copying any data.

   Prudence:

     Not all sequence types support passing the *start* and *stop*
     arguments.


Types de séquences immuables
----------------------------

La seule opération que les types de séquences immuables implémentent
et qui n'est pas implémentée par les types de séquences mutables est
la fonction native "hash()".

Cette implémentation permet d'utiliser des séquences immuables, comme
les instances de "n-uplets", en tant que clés de "dict" et stockées
dans les instances de "set" et "frozenset".

Essayer de hacher une séquence immuable qui contient des valeurs non
hachables lève une "TypeError".


Types de séquences mutables
---------------------------

Les opérations dans le tableau ci-dessous sont définies sur les types
de séquences mutables. La classe mère abstraite
"collections.abc.MutableSequence" est prévue pour faciliter
l'implémentation correcte de ces opérations sur les types de séquences
personnalisées.

Dans le tableau ci-dessosus, *s* est une instance d'un type de
séquence mutable, *t* est un objet itérable et *x* est un objet
arbitraire qui répond à toutes les restrictions de type et de valeur
imposées par *s* (par exemple, "bytearray" accepte uniquement des
nombres entiers qui répondent à la restriction de la valeur "0 <= x <=
255").

+--------------------------------+----------------------------------+-----------------------+
| Opération                      | Résultat                         | Notes                 |
|================================|==================================|=======================|
| "s[i] = x"                     | l'élément *i* de *s* est         |                       |
|                                | remplacé par *x*                 |                       |
+--------------------------------+----------------------------------+-----------------------+
| "del s[i]"                     | removes item *i* of *s*          |                       |
+--------------------------------+----------------------------------+-----------------------+
| "s[i:j] = t"                   | la tranche de *s* de *i* à *j*   |                       |
|                                | est remplacée par le contenu de  |                       |
|                                | l'itérable *t*                   |                       |
+--------------------------------+----------------------------------+-----------------------+
| "del s[i:j]"                   | removes the elements of "s[i:j]" |                       |
|                                | from the list (same as "s[i:j] = |                       |
|                                | []")                             |                       |
+--------------------------------+----------------------------------+-----------------------+
| "s[i:j:k] = t"                 | les éléments de "s[i:j:k]" sont  | (1)                   |
|                                | remplacés par ceux de *t*        |                       |
+--------------------------------+----------------------------------+-----------------------+
| "del s[i:j:k]"                 | supprime les éléments de         |                       |
|                                | "s[i:j:k]" de la liste           |                       |
+--------------------------------+----------------------------------+-----------------------+
| "s += t"                       | étend *s* avec le contenu de *t* |                       |
|                                | (proche de  "s[len(s):len(s)] =  |                       |
|                                | t")                              |                       |
+--------------------------------+----------------------------------+-----------------------+
| "s *= n"                       | met à jour *s* avec son contenu  | (2)                   |
|                                | répété *n* fois                  |                       |
+--------------------------------+----------------------------------+-----------------------+

Notes :

1. If *k* is not equal to "1", *t* must have the same length as the
   slice it is replacing.

2. La valeur *n* est un entier, ou un objet implémentant
   "__index__()". Zéro et les valeurs négatives de *n* permettent
   d'effacer la séquence. Les éléments dans la séquence ne sont pas
   copiés ; ils sont référencés plusieurs fois, comme expliqué pour "s
   * n" dans Opérations communes sur les séquences.

-[ Mutable Sequence Methods ]-

Mutable sequence types also support the following methods:

sequence.append(value, /)

   Append *value* to the end of the sequence This is equivalent to
   writing "seq[len(seq):len(seq)] = [value]".

sequence.clear()

   Ajouté dans la version 3.3.

   Remove all items from *sequence*. This is equivalent to writing
   "del sequence[:]".

sequence.copy()

   Ajouté dans la version 3.3.

   Create a shallow copy of *sequence*. This is equivalent to writing
   "sequence[:]".

   Indication:

     The "copy()" method is not part of the "MutableSequence" "ABC",
     but most concrete mutable sequence types provide it.

sequence.extend(iterable, /)

   Extend *sequence* with the contents of *iterable*. For the most
   part, this is the same as writing "seq[len(seq):len(seq)] =
   iterable".

sequence.insert(index, value, /)

   Insert *value* into *sequence* at the given *index*. This is
   equivalent to writing "sequence[index:index] = [value]".

sequence.pop(index=-1, /)

   Retrieve the item at *index* and also removes it from *sequence*.
   By default, the last item in *sequence* is removed and returned.

sequence.remove(value, /)

   Remove the first item from *sequence* where "sequence[i] == value".

   Raises "ValueError" if *value* is not found in *sequence*.

sequence.reverse()

   Reverse the items of *sequence* in place. This method maintains
   economy of space when reversing a large sequence. To remind users
   that it operates by side-effect, it returns "None".


Listes
------

Les listes sont des séquences mutables, généralement utilisées pour
stocker des collections d'éléments homogènes (le degré de similitude
varie selon l'usage).

class list(iterable=(), /)

   Les listes peuvent être construites de différentes manières :

   * en utilisant une paire de crochets pour indiquer une liste vide :
     "[]" ;

   * au moyen de crochets, en séparant les éléments par des virgules :
     "[a]", "[a, b, c]" ;

   * en utilisant une liste en compréhension : "[x for x in iterable]"
     ;

   * en utilisant le constructeur du type : "list()" ou
     "list(iterable)".

   Le constructeur crée une liste dont les éléments sont les mêmes et
   dans le même ordre que les éléments d'*iterable*. *iterable* peut
   être une séquence, un conteneur qui prend en charge l'itération, ou
   un itérateur. Si *iterable* est déjà une liste, une copie est faite
   et renvoyée, comme avec "iterable[:]". Par exemple, "list('abc')"
   renvoie "['a', 'b', 'c']" et "list( (1, 2, 3) )" renvoie "[1, 2,
   3]". Si aucun argument est donné, le constructeur crée une nouvelle
   liste vide, "[]".

   De nombreuses autres opérations produisent des listes, comme la
   fonction native "sorted()".

   Les listes gèrent toutes les opérations des séquences communes et
   mutables. Les listes fournissent également la méthode
   supplémentaire suivante :

   sort(*, key=None, reverse=False)

      Cette méthode trie la liste sur place, en utilisant uniquement
      des comparaisons "<" entre les éléments. Les exceptions ne sont
      pas supprimées : si n'importe quelle opération de comparaison
      échoue, le tri échoue (et la liste sera probablement laissée
      dans un état partiellement modifié).

      "sort()" accepte deux arguments qui ne peuvent être fournis que
      nommés (voir arguments nommés) :

      *key* spécifie une fonction d'un argument utilisée pour extraire
      une clé de comparaison de chaque élément de la liste (par
      exemple, "key=str.lower"). La clé correspondant à chaque élément
      de la liste n'est calculée qu'une seule fois, puis utilisée
      durant tout le processus. La valeur par défaut, "None", signifie
      que les éléments sont triés directement sans calculer de «
      valeur clé » séparée.

      La fonction utilitaire "functools.cmp_to_key()" est disponible
      pour convertir une fonction *cmp* du style 2.x à une fonction
      *key*.

      *reverse*, une valeur booléenne. Si elle est "True", la liste
      d'éléments est triée comme si toutes les comparaisons étaient
      inversées.

      Cette méthode modifie la séquence sur place pour économiser de
      l'espace lors du tri de grandes séquences. Pour rappeler aux
      utilisateurs cet effet de bord, elle ne renvoie pas la séquence
      triée (utilisez "sorted()" pour demander explicitement une
      nouvelle instance de liste triée).

      La méthode "sort()" est garantie stable. Un tri est stable s'il
      garantit de ne pas changer l'ordre relatif des éléments égaux —
      cela est utile pour trier en plusieurs passes (par exemple,
      trier par service, puis par niveau de salaire).

      Pour des exemples de tris et un bref tutoriel, consultez Les
      techniques de tri.

      l'effet de tenter de modifier, ou même inspecter la liste
      pendant qu'on la trie est indéfini. L'implémentation C de Python
      fait apparaître la liste comme vide pour la durée du traitement,
      et lève "ValueError" si elle détecte que la liste a été modifiée
      au cours du tri.

-[ Thread safety for list objects ]-

Reading a single element from a "list" is *atomic*:

   lst[i]   # list.__getitem__

The following methods traverse the list and use *atomic* reads of each
item to perform their function. That means that they may return
results affected by concurrent modifications:

   item in lst
   lst.index(item)
   lst.count(item)

All of the above operations avoid acquiring *per-object locks*. They
do not block concurrent modifications. Other operations that hold a
lock will not block these from observing intermediate states.

All other operations from here on block using the *per-object lock*.

Writing a single item via "lst[i] = x" is safe to call from multiple
threads and will not corrupt the list.

The following operations return new objects and appear *atomic* to
other threads:

   lst1 + lst2    # concatenates two lists into a new list
   x * lst        # repeats lst x times into a new list
   lst.copy()     # returns a shallow copy of the list

The following methods that only operate on a single element with no
shifting required are *atomic*:

   lst.append(x)  # append to the end of the list, no shifting required
   lst.pop()      # pop element from the end of the list, no shifting required

The "clear()" method is also *atomic*. Other threads cannot observe
elements being removed.

The "sort()" method is not *atomic*. Other threads cannot observe
intermediate states during sorting, but the list appears empty for the
duration of the sort.

The following operations may allow *lock-free* operations to observe
intermediate states since they modify multiple elements in place:

   lst.insert(idx, item)  # shifts elements
   lst.pop(idx)           # idx not at the end of the list, shifts elements
   lst *= x               # copies elements in place

The "remove()" method may allow concurrent modifications since element
comparison may execute arbitrary Python code (via "__eq__()").

"extend()" is safe to call from multiple threads.  However, its
guarantees depend on the iterable passed to it. If it is a "list", a
"tuple", a "set", a "frozenset", a "dict" or a dictionary view object
(but not their subclasses), the "extend" operation is safe from
concurrent modifications to the iterable. Otherwise, an iterator is
created which can be concurrently modified by another thread.  The
same applies to inplace concatenation of a list with other iterables
when using "lst += iterable".

Similarly, assigning to a list slice with "lst[i:j] = iterable" is
safe to call from multiple threads, but "iterable" is only locked when
it is also a "list" (but not its subclasses).

Operations that involve multiple accesses, as well as iteration, are
never atomic. For example:

   # NOT atomic: read-modify-write
   lst[i] = lst[i] + 1

   # NOT atomic: check-then-act
   if lst:
         item = lst.pop()

   # NOT thread-safe: iteration while modifying
   for item in lst:
         process(item)  # another thread may modify lst

Consider external synchronization when sharing "list" instances across
threads.  See Python support for free threading for more information.


*N*-uplets
----------

Les *n*-uplets (*tuples* en anglais) sont des séquences immuables,
généralement utilisées pour stocker des collections de données
hétérogènes (telles que les paires produites par la fonction native
"enumerate()"). Les *n*-uplets sont également utilisés dans des cas où
une séquence homogène et immuable de données  est nécessaire (pour,
par exemple, les stocker dans un "ensemble" ou un "dictionnaire").

class tuple(iterable=(), /)

   Les *n*-uplets peuvent être construits de différentes façons :

   * en utilisant une paire de parenthèses pour désigner le *n*-uplet
     vide : "()" ;

   * en utilisant une virgule, pour créer un *n*-uplet d'un élément :
     "a," ou "(a,)" ;

   * en séparant les éléments avec des virgules : "a, b, c" ou "(a, b,
     c)" ;

   * en utilisant la fonction native "tuple()" : "tuple()" ou
     "tuple(iterable)".

   Le constructeur construit un *n*-uplet dont les éléments sont les
   mêmes et dans le même ordre que les éléments de *iterable*.
   *iterable* peut être une séquence, un conteneur qui prend en charge
   l'itération ou un itérateur. Si *iterable* est déjà un *n*-uplet,
   il est renvoyé inchangé. Par exemple, "tuple('abc')" renvoie "('a',
   'b', 'c')" et "tuple( [1, 2, 3] )" renvoie "(1, 2, 3)". Si aucun
   argument n'est donné, le constructeur crée un nouveau *n*-uplet
   vide, "()".

   Notez que c'est en fait la virgule qui fait un *n*-uplet et non les
   parenthèses. Les parenthèses sont facultatives, sauf dans le cas du
   *n*-uplet vide, ou lorsqu'elles sont nécessaires pour éviter
   l'ambiguïté syntaxique. Par exemple, "f(a, b, c)" est un appel de
   fonction avec trois arguments, alors que "f((a, b, c))" est un
   appel de fonction avec un triplet comme unique argument.

   Les *n*-uplets implémentent toutes les opérations communes des
   séquences.

Pour les collections hétérogènes de données où l'accès par nom est
plus clair que l'accès par indice, "collections.namedtuple()" peut
être un choix plus approprié qu'un simple *n*-uplet.


*Ranges*
--------

Le type "range" représente une séquence immuable de nombres et est
couramment utilisé pour itérer un certain nombre de fois dans les
boucles "for".

class range(stop, /)
class range(start, stop, step=1, /)

   Les arguments du constructeur de *range* doivent être des entiers
   (des "int" ou tout autre objet qui implémente la méthode spéciale
   "__index__()"). La valeur par défaut de l'argument *step* est "1".
   La valeur par défaut de l'argument *start* est "0". Si *step* est
   égal à zéro, une exception "ValueError" est levée.

   Pour un *step* positif, le contenu d'un *range* "r" est déterminé
   par la formule "r[i] = start + step*i" où "i >= 0" et "r[i] <
   stop".

   Pour un *step* négatif, le contenu du *range* est toujours
   déterminé par la formule "r[i] = start + step*i", mais les
   contraintes sont "i >= 0" et "r[i] > stop".

   Un objet *range* sera vide si "r[0]" ne répond pas à la contrainte
   de valeur. Les *range* prennent en charge les indices négatifs,
   mais ceux-ci sont interprétées comme un indice à partir de la fin
   de la séquence déterminée par les indices positifs.

   Les *range* contenant des valeurs absolues plus grandes que
   "sys.maxsize" sont permises, mais certaines fonctionnalités (comme
   "len()") peuvent lever "OverflowError".

   Exemples avec *range* :

      >>> list(range(10))
      [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      >>> list(range(1, 11))
      [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      >>> list(range(0, 30, 5))
      [0, 5, 10, 15, 20, 25]
      >>> list(range(0, 10, 3))
      [0, 3, 6, 9]
      >>> list(range(0, -10, -1))
      [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
      >>> list(range(0))
      []
      >>> list(range(1, 0))
      []

   *range* implémente toutes les opérations communes des séquences
   sauf la concaténation et la répétition (en raison du fait que les
   *range* ne peuvent représenter que des séquences qui respectent un
   motif strict et que la répétition et la concaténation les feraient
   dévier de ce motif).

   start

      Valeur du paramètre *start* (ou "0" si le paramètre n'a pas été
      fourni)

   stop

      Valeur du paramètre *stop*

   step

      Valeur du paramètre *step* (ou "1" si le paramètre n'a pas été
      fourni)

L'avantage du type "range" sur une "liste" classique ou un "n-uplet"
est qu'un objet "range" occupe toujours la même (petite) quantité de
mémoire, peu importe la taille de l'intervalle qu'il représente (car
il ne stocke que les valeurs "start", "stop", "step", le calcul des
éléments individuels et les sous-intervalles au besoin).

Les *range* implémentent la classe mère abstraite
"collections.abc.Sequence" et offrent des fonctionnalités telles que
les tests d'appartenance (avec *in*), de recherche par indice, les
tranches et ils gèrent les indices négatifs (voir Types séquentiels —
list, tuple, range) :

>>> r = range(0, 20, 2)
>>> r
range(0, 20, 2)
>>> 11 in r
False
>>> 10 in r
True
>>> r.index(10)
5
>>> r[5]
10
>>> r[:5]
range(0, 10, 2)
>>> r[-1]
18

Comparer des *range* avec "==" et "!=" les compare comme des
séquences. C'est-à-dire que deux objets *range* sont considérés comme
égaux s'ils représentent la même séquence de valeurs. (Notez que deux
objets *range* dits égaux pourraient avoir leurs attributs "start",
"stop" et "step" différents, par exemple "range(0) == range(2, 1, 3)"
ou "range(0, 3, 2) == range(0, 4, 2)".)

Modifié dans la version 3.2: implémente la classe mère abstraite
*Sequence*. prend en charge les tranches (*slicing*) et les indices
négatifs. Teste l'appartenance d'un "int" en temps constant au lieu
d'itérer sur tous les éléments.

Modifié dans la version 3.3: "==" et "!=" comparent des *range* en
fonction de la séquence de valeurs qu'ils définissent (au lieu d'une
comparaison fondée sur l'identité de l'objet).Added the "start",
"stop" and "step" attributes.

Voir aussi:

  * The linspace recipe shows how to implement a lazy version of range
    suitable for floating-point applications.


Text and Binary Sequence Type Methods Summary
=============================================

The following table summarizes the text and binary sequence types
methods by category.

+----------------------------+--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
| Catégorie                  | "str" methods                                                     | "bytes" and "bytearray" methods                                           |
|============================|====================|==========|==========|========================|======================|==========|==========|==============================|
| Formatting                 | "str.format()"                                                    |                                                                           |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.format_map()"                                                |                                                                           |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | f-strings                                                         |                                                                           |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | Formatage de chaines à la printf                                  | Formatage de bytes a la printf                                            |
+----------------------------+--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
| Searching and Replacing    | "str.find()"       | "str.rfind()"                                | "bytes.find()"       | "bytes.rfind()"                                    |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.index()"      | "str.rindex()"                               | "bytes.index()"      | "bytes.rindex()"                                   |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.startswith()"                                                | "bytes.startswith()"                                                      |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.endswith()"                                                  | "bytes.endswith()"                                                        |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.count()"                                                     | "bytes.count()"                                                           |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.replace()"                                                   | "bytes.replace()"                                                         |
+----------------------------+--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
| Splitting and Joining      | "str.split()"                 | "str.rsplit()"                    | "bytes.split()"                 | "bytes.rsplit()"                        |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.splitlines()"                                                | "bytes.splitlines()"                                                      |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.partition()"                                                 | "bytes.partition()"                                                       |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.rpartition()"                                                | "bytes.rpartition()"                                                      |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.join()"                                                      | "bytes.join()"                                                            |
+----------------------------+--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
| String Classification      | "str.isalpha()"                                                   | "bytes.isalpha()"                                                         |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.isdecimal()"                                                 |                                                                           |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.isdigit()"                                                   | "bytes.isdigit()"                                                         |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.isnumeric()"                                                 |                                                                           |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.isalnum()"                                                   | "bytes.isalnum()"                                                         |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.isidentifier()"                                              |                                                                           |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.islower()"                                                   | "bytes.islower()"                                                         |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.isupper()"                                                   | "bytes.isupper()"                                                         |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.istitle()"                                                   | "bytes.istitle()"                                                         |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.isspace()"                                                   | "bytes.isspace()"                                                         |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.isprintable()"                                               |                                                                           |
+----------------------------+--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
| Case Manipulation          | "str.lower()"                                                     | "bytes.lower()"                                                           |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.upper()"                                                     | "bytes.upper()"                                                           |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.casefold()"                                                  |                                                                           |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.capitalize()"                                                | "bytes.capitalize()"                                                      |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.title()"                                                     | "bytes.title()"                                                           |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.swapcase()"                                                  | "bytes.swapcase()"                                                        |
+----------------------------+--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
| Padding and Stripping      | "str.ljust()"                 | "str.rjust()"                     | "bytes.ljust()"                 | "bytes.rjust()"                         |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.center()"                                                    | "bytes.center()"                                                          |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.expandtabs()"                                                | "bytes.expandtabs()"                                                      |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.strip()"                                                     | "bytes.strip()"                                                           |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.lstrip()"                           | "str.rstrip()"         | "bytes.lstrip()"                           | "bytes.rstrip()"             |
+----------------------------+--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
| Translation and Encoding   | "str.translate()"                                                 | "bytes.translate()"                                                       |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.maketrans()"                                                 | "bytes.maketrans()"                                                       |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            | "str.encode()"                                                    |                                                                           |
|                            +--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+
|                            |                                                                   | "bytes.decode()"                                                          |
+----------------------------+--------------------+----------+----------+------------------------+----------------------+----------+----------+------------------------------+


Type Séquence de Texte — "str"
==============================

Les données textuelles en Python sont manipulées avec des objets "str"
ou *strings*. Les chaînes sont  des séquences immuables de points de
code Unicode. Les chaînes littérales peuvent être écrites de
différentes manières :

* entre guillemets simples : "'cela autorise les "guillemets
  anglais"'" ;

* entre guillemets (anglais) : ""cela autorise les guillemets
  'simples'"" ;

* entre guillemets triples : "'''Trois guillemets simples'''",
  """"Trois guillemets anglais"""".

Les chaînes entre guillemets triples peuvent couvrir plusieurs lignes,
tous les espaces associées sont alors incluses dans la chaîne
littérale.

Les chaînes littérales qui font partie d'une seule expression et ont
seulement des espaces entre elles sont implicitement converties en une
seule chaîne littérale. Autrement dit, "("spam " "eggs") == "spam
eggs"".

See Littéraux de chaînes de caractères et de suites d'octets for more
about the various forms of string literal, including supported escape
sequences, and the "r" ("raw") prefix that disables most escape
sequence processing.

Les chaînes peuvent également être créées à partir d'autres objets à
l'aide du constructeur "str".

Comme il n'y a pas de type « caractère » propre, un indice d'une
chaîne produit une chaîne de longueur 1. Autrement dit, pour une
chaîne non vide *s*, "s[0] == s[0:1]".

Il n'y a aucun type de chaîne mutable, mais "str.join()" ou
"io.StringIO" peuvent être utilisées pour construire efficacement des
chaînes à partir de plusieurs fragments.

Modifié dans la version 3.3: pour une compatibilité ascendante avec la
série Python 2, le préfixe "u" est à nouveau autorisé sur les chaînes
littérales. Il n'a aucun effet sur le sens des chaînes littérales et
ne peut pas être combiné avec le préfixe "r".

class str(*, encoding='utf-8', errors='strict')
class str(object)
class str(object, encoding, errors='strict')
class str(object, *, errors)

   Renvoie une représentation en chaîne de caractères de *object*. Si
   *object* n'est pas fourni, renvoie une chaîne vide. Sinon, le
   comportement de "str()" dépend des valeurs données pour *encoding*
   et *errors*, comme indiqué ci-dessous.

   If neither *encoding* nor *errors* is given, "str(object)" returns
   "type(object).__str__(object)", which is the "informal" or nicely
   printable string representation of *object*.  For string objects,
   this is the string itself.  If *object* does not have a "__str__()"
   method, then "str()" falls back to returning "repr(object)".

   Si au moins un des deux arguments *encoding* ou *errors* est donné,
   *object* doit être un *objet octet-compatible* (par exemple,
   "bytes" ou "bytearray"). Dans ce cas, si *object* est un objet
   "bytes" (ou "bytearray"), alors "str(bytes, encoding, errors)" est
   équivalent à "bytes.decode(encoding, errors)". Sinon, l'objet
   *bytes* sous-jacent au tampon est obtenu avant d'appeler
   "bytes.decode()". Voir Séquences Binaires — bytes, bytearray, vue
   mémoire et Protocole tampon pour plus d'informations sur les
   tampons.

   Donner un objet "bytes" à "str()" sans argument *encoding* ni
   argument *errors* relève du premier cas, où la représentation
   informelle de la chaîne est renvoyée (voir aussi l'option "-b" de
   Python). Par exemple :

      >>> str(b'Zoot!')
      "b'Zoot!'"

   Pour plus d'informations sur la classe "str" et ses méthodes, voir
   les sections Type Séquence de Texte — str et Méthodes de chaînes de
   caractères. Pour formater des chaînes de caractères, voir les
   sections f-strings et Syntaxe de formatage de chaîne. La section
   Services de Manipulation de Texte contient aussi des informations.


Méthodes de chaînes de caractères
---------------------------------

Les chaînes implémentent toutes les opérations communes des séquences,
ainsi que les autres méthodes décrites ci-dessous.

Les chaînes gèrent aussi deux styles de mise en forme, l'un
fournissant une grande flexibilité et de personnalisation (voir
"str.format()", Syntaxe de formatage de chaîne et Formatage
personnalisé de chaîne) et l'autre basée sur le style de formatage de
"printf" du C qui gère une gamme plus étroite de types et est
légèrement plus difficile à utiliser correctement, mais qui est
souvent plus rapide pour les cas pris en charge (Formatage de chaines
à la printf).

La section Services de Manipulation de Texte de la bibliothèque
standard couvre un certain nombre d'autres modules qui fournissent
différents services relatifs au texte (y compris les expressions
rationnelles dans le module "re").

str.capitalize()

   Renvoie une copie de la chaîne avec son premier caractère en
   majuscule et le reste en minuscule.

   Modifié dans la version 3.8: le premier caractère est maintenant
   mis en *titlecase* plutôt qu'en majuscule. Cela veut dire que les
   caractères comme les digrammes auront seulement leur première
   lettre en majuscule, au lieu du caractère en entier.

str.casefold()

   Renvoie une copie *casefolded* de la chaîne. Les chaînes
   *casefolded* peuvent être utilisées dans des comparaisons
   insensibles à la casse.

   Casefolding is similar to lowercasing but more aggressive because
   it is intended to remove all case distinctions in a string. For
   example, the German lowercase letter "'ß'" is equivalent to ""ss"".
   Since it is already lowercase, "lower()" would do nothing to "'ß'";
   "casefold()" converts it to ""ss"". For example:

      >>> 'straße'.lower()
      'straße'
      >>> 'straße'.casefold()
      'strasse'

   The casefolding algorithm is described in section 3.13 'Default
   Case Folding' of the Unicode Standard.

   Ajouté dans la version 3.3.

str.center(width, fillchar=' ', /)

   Return centered in a string of length *width*. Padding is done
   using the specified *fillchar* (default is an ASCII space). The
   original string is returned if *width* is less than or equal to
   "len(s)".  For example:

      >>> 'Python'.center(10)
      '  Python  '
      >>> 'Python'.center(10, '-')
      '--Python--'
      >>> 'Python'.center(4)
      'Python'

str.count(sub[, start[, end]])

   Renvoie le nombre d'occurrences de *sub* ne se chevauchant pas dans
   l'intervalle [*start*, *end*]. Les arguments facultatifs *start* et
   *end* sont interprétés comme dans la notation des tranches
   (*slices* en anglais).

   If *sub* is empty, returns the number of empty strings between
   characters which is the length of the string plus one. For example:

      >>> 'spam, spam, spam'.count('spam')
      3
      >>> 'spam, spam, spam'.count('spam', 5)
      2
      >>> 'spam, spam, spam'.count('spam', 5, 10)
      1
      >>> 'spam, spam, spam'.count('eggs')
      0
      >>> 'spam, spam, spam'.count('')
      17

str.encode(encoding='utf-8', errors='strict')

   Renvoie la chaine encodée dans une instance de "bytes".

   *encoding* vaut par défaut "utf-8" ; pour une liste des encodages
   possibles, voir la section Standard Encodings.

   *errors* détermine la manière dont les erreurs sont traitées. La
   valeur par défaut est "'strict'", ce qui signifie que les erreurs
   d'encodage lèvent une "UnicodeError". Les autres valeurs possibles
   sont "'ignore'", "'replace'", "'xmlcharrefreplace'",
   "'backslashreplace'" et tout autre nom enregistré *via*
   "codecs.register_error()". Voir la section Gestionnaires d'erreurs
   pour plus de détails.

   For performance reasons, the value of *errors* is not checked for
   validity unless an encoding error actually occurs, Python
   Development Mode is enabled or a debug build is used. For example:

      >>> encoded_str_to_bytes = 'Python'.encode()
      >>> type(encoded_str_to_bytes)
      <class 'bytes'>
      >>> encoded_str_to_bytes
      b'Python'

   Modifié dans la version 3.1: gère les arguments nommés.

   Modifié dans la version 3.9: les valeurs de *errors* sont
   maintenant vérifiées en mode de développement et en mode de
   débogage.

str.endswith(suffix[, start[, end]])

   Return "True" if the string ends with the specified *suffix*,
   otherwise return "False".  *suffix* can also be a tuple of suffixes
   to look for.  With optional *start*, test beginning at that
   position.  With optional *end*, stop comparing at that position.
   Using *start* and *end* is equivalent to
   "str[start:end].endswith(suffix)". For example:

      >>> 'Python'.endswith('on')
      True
      >>> 'a tuple of suffixes'.endswith(('at', 'in'))
      False
      >>> 'a tuple of suffixes'.endswith(('at', 'es'))
      True
      >>> 'Python is amazing'.endswith('is', 0, 9)
      True

   See also "startswith()" and "removesuffix()".

str.expandtabs(tabsize=8)

   Return a copy of the string where all tab characters are replaced
   by one or more spaces, depending on the current column and the
   given tab size.  Tab positions occur every *tabsize* characters
   (default is 8, giving tab positions at columns 0, 8, 16 and so on).
   To expand the string, the current column is set to zero and the
   string is examined character by character.  If the character is a
   tab ("\t"), one or more space characters are inserted in the result
   until the current column is equal to the next tab position. (The
   tab character itself is not copied.)  If the character is a newline
   ("\n") or return ("\r"), it is copied and the current column is
   reset to zero.  Any other character is copied unchanged and the
   current column is incremented by one regardless of how the
   character is represented when printed. For example:

      >>> '01\t012\t0123\t01234'.expandtabs()
      '01      012     0123    01234'
      >>> '01\t012\t0123\t01234'.expandtabs(4)
      '01  012 0123    01234'
      >>> print('01\t012\n0123\t01234'.expandtabs(4))
      01  012
      0123    01234

str.find(sub[, start[, end]])

   Return the lowest index in the string where substring *sub* is
   found within the slice "s[start:end]".  Optional arguments *start*
   and *end* are interpreted as in slice notation.  Return "-1" if
   *sub* is not found. For example:

      >>> 'spam, spam, spam'.find('sp')
      0
      >>> 'spam, spam, spam'.find('sp', 5)
      6

   See also "rfind()" and "index()".

   Note:

     la méthode "find()" ne doit être utilisée que si vous avez besoin
     de connaître la position de *sub*. Pour vérifier si *sub* est une
     sous chaine ou non, utilisez l'opérateur "in" :

        >>> 'Py' in 'Python'
        True

str.format(*args, **kwargs)

   Perform a string formatting operation.  The string on which this
   method is called can contain literal text or replacement fields
   delimited by braces "{}".  Each replacement field contains either
   the numeric index of a positional argument, or the name of a
   keyword argument.  Returns a copy of the string where each
   replacement field is replaced with the string value of the
   corresponding argument. For example:

      >>> "The sum of 1 + 2 is {0}".format(1+2)
      'The sum of 1 + 2 is 3'
      >>> "The sum of {a} + {b} is {answer}".format(answer=1+2, a=1, b=2)
      'The sum of 1 + 2 is 3'
      >>> "{1} expects the {0} Inquisition!".format("Spanish", "Nobody")
      'Nobody expects the Spanish Inquisition!'

   Voir Syntaxe de formatage de chaîne pour une description des
   options de formatage qui peuvent être spécifiées dans les chaînes
   de format.

   Note:

     lors du formatage avec le format "n" (comme
     "'{:n}'.format(1234)") d'un nombre ("int", "float", "complex",
     "decimal.Decimal" et classes dérivées), la fonction met
     temporairement la variable "LC_CTYPE" à la valeur de "LC_NUMERIC"
     pour décoder correctement les attributs "decimal_point" et
     "thousands_sep" de "localeconv()", s'ils ne sont pas en ASCII ou
     font plus d'un octet et que "LC_NUMERIC" est différent de
     "LC_CTYPE". Ce changement temporaire affecte les autres fils
     d'exécution.

   Modifié dans la version 3.7: lors du formatage d'un nombre avec le
   format "n", la fonction change temporairement "LC_CTYPE" par la
   valeur de "LC_NUMERIC" dans certains cas.

str.format_map(mapping, /)

   Semblable à "str.format(**mapping)", sauf que "mapping" est utilisé
   directement et non copié dans un "dict". C'est utile si, par
   exemple, "mapping" est une sous-classe de "dict" :

   >>> class Default(dict):
   ...     def __missing__(self, key):
   ...         return key
   ...
   >>> '{name} was born in {country}'.format_map(Default(name='Guido'))
   'Guido was born in country'

   Ajouté dans la version 3.2.

str.index(sub[, start[, end]])

   Like "find()", but raise "ValueError" when the substring is not
   found. For example:

      >>> 'spam, spam, spam'.index('spam')
      0
      >>> 'spam, spam, spam'.index('eggs')
      Traceback (most recent call last):
        File "<python-input-0>", line 1, in <module>
          'spam, spam, spam'.index('eggs')
          ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
      ValueError: substring not found

   See also "rindex()".

str.isalnum()

   Return "True" if all characters in the string are alphanumeric and
   there is at least one character, "False" otherwise.  A character
   "c" is alphanumeric if one of the following returns "True":
   "c.isalpha()", "c.isdecimal()", "c.isdigit()", or "c.isnumeric()".
   For example:

      .. doctest::

   >>> 'abc123'.isalnum()
   True
   >>> 'abc123!@#'.isalnum()
   False
   >>> ''.isalnum()
   False
   >>> ' '.isalnum()
   False

str.isalpha()

   Return "True" if all characters in the string are alphabetic and
   there is at least one character, "False" otherwise.  Alphabetic
   characters are those characters defined in the Unicode character
   database as "Letter", i.e., those with general category property
   being one of "Lm", "Lt", "Lu", "Ll", or "Lo".  Note that this is
   different from the Alphabetic property defined in the section 4.10
   'Letters, Alphabetic, and Ideographic' of the Unicode Standard. For
   example:

      >>> 'Letters and spaces'.isalpha()
      False
      >>> 'LettersOnly'.isalpha()
      True
      >>> 'µ'.isalpha()  # non-ASCII characters can be considered alphabetical too
      True

   See Propriétés Unicode.

str.isascii()

   Return "True" if the string is empty or all characters in the
   string are ASCII, "False" otherwise. ASCII characters have code
   points in the range U+0000-U+007F. For example:

      >>> 'ASCII characters'.isascii()
      True
      >>> 'µ'.isascii()
      False

   Ajouté dans la version 3.7.

str.isdecimal()

   Return "True" if all characters in the string are decimal
   characters and there is at least one character, "False" otherwise.
   Decimal characters are those that can be used to form numbers in
   base 10, such as U+0660, ARABIC-INDIC DIGIT ZERO.  Formally a
   decimal character is a character in the Unicode General Category
   "Nd". For example:

      >>> '0123456789'.isdecimal()
      True
      >>> '٠١٢٣٤٥٦٧٨٩'.isdecimal()  # Arabic-Indic digits zero to nine
      True
      >>> 'alphabetic'.isdecimal()
      False

str.isdigit()

   Renvoie "True" si tous les caractères de la chaîne sont des
   chiffres et qu'elle contient au moins un caractère, "False" sinon.
   Les chiffres incluent des caractères décimaux et des chiffres qui
   nécessitent une manipulation particulière, tels que les
   *compatibility superscript digits*. Ça couvre les chiffres qui ne
   peuvent pas être utilisés pour construire des nombres en base 10,
   tels que les nombres de Kharosthi. Formellement, un chiffre est un
   caractère dont la valeur de la propriété *Numeric_Type* est *Digit*
   ou *Decimal*.

str.isidentifier()

   Renvoie "True" si la chaîne est un identifiant valide selon la
   définition du langage, section Names (identifiers and keywords).

   "keyword.iskeyword()" can be used to test whether string "s" is a
   reserved identifier, such as "def" and "class".

   Par exemple :

      >>> from keyword import iskeyword

      >>> 'hello'.isidentifier(), iskeyword('hello')
      (True, False)
      >>> 'def'.isidentifier(), iskeyword('def')
      (True, True)

str.islower()

   Renvoie "True" si tous les caractères capitalisables [4] de la
   chaîne sont en minuscules et qu'elle contient au moins un caractère
   capitalisable. Renvoie "False" dans le cas contraire.

str.isnumeric()

   Return "True" if all characters in the string are numeric
   characters, and there is at least one character, "False" otherwise.
   Numeric characters include digit characters, and all characters
   that have the Unicode numeric value property, e.g. U+2155, VULGAR
   FRACTION ONE FIFTH.  Formally, numeric characters are those with
   the property value Numeric_Type=Digit, Numeric_Type=Decimal or
   Numeric_Type=Numeric. For example:

      >>> '0123456789'.isnumeric()
      True
      >>> '٠١٢٣٤٥٦٧٨٩'.isnumeric()  # Arabic-indic digit zero to nine
      True
      >>> '⅕'.isnumeric()  # Vulgar fraction one fifth
      True
      >>> '²'.isdecimal(), '²'.isdigit(),  '²'.isnumeric()
      (False, True, True)

   See also "isdecimal()" and "isdigit()". Numeric characters are a
   superset of decimal numbers.

str.isprintable()

   Return "True" if all characters in the string are printable,
   "False" if it contains at least one non-printable character.

   Here "printable" means the character is suitable for "repr()" to
   use in its output; "non-printable" means that "repr()" on built-in
   types will hex-escape the character.  It has no bearing on the
   handling of strings written to "sys.stdout" or "sys.stderr".

   The printable characters are those which in the Unicode character
   database (see "unicodedata") have a general category in group
   Letter, Mark, Number, Punctuation, or Symbol (L, M, N, P, or S);
   plus the ASCII space 0x20. Nonprintable characters are those in
   group Separator or Other (Z or C), except the ASCII space.

   For example:

      >>> ''.isprintable(), ' '.isprintable()
      (True, True)
      >>> '\t'.isprintable(), '\n'.isprintable()
      (False, False)

str.isspace()

   Renvoie "True" s'il n'y a que des caractères d'espacement dans la
   chaîne et qu'elle comporte au moins un caractère. Renvoie "False"
   dans le cas contraire.

   Un caractère est considéré comme un caractère d'espacement
   (*whitespace* en anglais) si, dans la base de données caractères
   Unicode (voir "unicodedata"), sa catégorie générale est "Zs" («
   séparateur, espace »), ou sa classe bidirectionnelle est une de
   "WS", "B", ou "S".

str.istitle()

   Renvoie "True" si la chaîne est une chaîne *titlecased* et qu'elle
   contient au moins un caractère, par exemple les caractères
   majuscules ne peuvent suivre les caractères non capitalisables et
   les caractères minuscules ne peuvent suivre que des caractères
   capitalisables. Renvoie "False" dans le cas contraire.

   For example:

      >>> 'Spam, Spam, Spam'.istitle()
      True
      >>> 'spam, spam, spam'.istitle()
      False
      >>> 'SPAM, SPAM, SPAM'.istitle()
      False

   See also "title()".

str.isupper()

   Renvoie "True" si tous les caractères différentiables sur la casse
   [4] de la chaîne sont en majuscules et s'il y a au moins un
   caractère différentiable sur la casse, sinon "False".

   >>> 'BANANA'.isupper()
   True
   >>> 'banana'.isupper()
   False
   >>> 'baNana'.isupper()
   False
   >>> ' '.isupper()
   False

str.join(iterable, /)

   Return a string which is the concatenation of the strings in
   *iterable*. A "TypeError" will be raised if there are any non-
   string values in *iterable*, including "bytes" objects.  The
   separator between elements is the string providing this method. For
   example:

      >>> ', '.join(['spam', 'spam', 'spam'])
      'spam, spam, spam'
      >>> '-'.join('Python')
      'P-y-t-h-o-n'

   See also "split()".

str.ljust(width, fillchar=' ', /)

   Renvoie la chaîne justifiée à gauche dans une chaîne de longueur
   *width*. Le bourrage est fait en utilisant *fillchar* (qui par
   défaut est une espace ASCII). La chaîne d'origine est renvoyée si
   *width* est inférieure ou égale à "len(s)".

   For example:

      >>> 'Python'.ljust(10)
      'Python    '
      >>> 'Python'.ljust(10, '.')
      'Python....'
      >>> 'Monty Python'.ljust(10, '.')
      'Monty Python'

   See also "rjust()".

str.lower()

   Return a copy of the string with all the cased characters [4]
   converted to lowercase. For example:

      >>> 'Lower Method Example'.lower()
      'lower method example'

   The lowercasing algorithm used is described in section 3.13
   'Default Case Folding' of the Unicode Standard.

str.lstrip(chars=None, /)

   Renvoie une copie de la chaîne avec des caractères supprimés au
   début. L'argument *chars* est une chaîne spécifiant le jeu de
   caractères à supprimer. En cas d'omission ou "None", la valeur par
   défaut de *chars* permet de supprimer des caractères d'espacement.
   L'argument *chars* n'est pas un préfixe, toutes les combinaisons de
   ses valeurs sont supprimées :

      >>> '   spacious   '.lstrip()
      'spacious   '
      >>> 'www.example.com'.lstrip('cmowz.')
      'example.com'

   Voir "str.removeprefix()" pour une méthode qui supprime une seule
   chaîne de préfixe plutôt que la totalité d'un ensemble de
   caractères. Par exemple :

      >>> 'Arthur: three!'.lstrip('Arthur: ')
      'ee!'
      >>> 'Arthur: three!'.removeprefix('Arthur: ')
      'three!'

static str.maketrans(dict, /)
static str.maketrans(from, to, remove='', /)

   Cette méthode statique renvoie une table de traduction utilisable
   pour "str.translate()".

   Si un seul argument est fourni, ce soit être un dictionnaire
   faisant correspondre des points de code Unicode (nombres entiers)
   ou des caractères (chaînes de longueur 1) à des points de code
   Unicode.

   If there are two arguments, they must be strings of equal length,
   and in the resulting dictionary, each character in *from* will be
   mapped to the character at the same position in *to*.  If there is
   a third argument, it must be a string, whose characters will be
   mapped to "None" in the result.

str.partition(sep, /)

   Divise la chaîne à la première occurrence de *sep*, et renvoie un
   triplet contenant la partie avant le séparateur, le séparateur lui-
   même, et la partie après le séparateur. Si le séparateur n'est pas
   trouvé, le triplet contient la chaîne elle-même, suivie de deux
   chaînes vides.

   For example:

      >>> 'Monty Python'.partition(' ')
      ('Monty', ' ', 'Python')
      >>> "Monty Python's Flying Circus".partition(' ')
      ('Monty', ' ', "Python's Flying Circus")
      >>> 'Monty Python'.partition('-')
      ('Monty Python', '', '')

   See also "rpartition()".

str.removeprefix(prefix, /)

   If the string starts with the *prefix* string, return
   "string[len(prefix):]". Otherwise, return a copy of the original
   string:

      >>> 'TestHook'.removeprefix('Test')
      'Hook'
      >>> 'BaseTestCase'.removeprefix('Test')
      'BaseTestCase'

   Ajouté dans la version 3.9.

   See also "removesuffix()" and "startswith()".

str.removesuffix(suffix, /)

   If the string ends with the *suffix* string and that *suffix* is
   not empty, return "string[:-len(suffix)]". Otherwise, return a copy
   of the original string:

      >>> 'MiscTests'.removesuffix('Tests')
      'Misc'
      >>> 'TmpDirMixin'.removesuffix('Tests')
      'TmpDirMixin'

   Ajouté dans la version 3.9.

   See also "removeprefix()" and "endswith()".

str.replace(old, new, /, count=-1)

   Return a copy of the string with all occurrences of substring *old*
   replaced by *new*.  If *count* is given, only the first *count*
   occurrences are replaced. If *count* is not specified or "-1", then
   all occurrences are replaced. For example:

      >>> 'spam, spam, spam'.replace('spam', 'eggs')
      'eggs, eggs, eggs'
      >>> 'spam, spam, spam'.replace('spam', 'eggs', 1)
      'eggs, spam, spam'

   Modifié dans la version 3.13: *count* is now supported as a keyword
   argument.

str.rfind(sub[, start[, end]])

   Return the highest index in the string where substring *sub* is
   found, such that *sub* is contained within "s[start:end]".
   Optional arguments *start* and *end* are interpreted as in slice
   notation.  Return "-1" on failure. For example:

      >>> 'spam, spam, spam'.rfind('sp')
      12
      >>> 'spam, spam, spam'.rfind('sp', 0, 10)
      6

   See also "find()" and "rindex()".

str.rindex(sub[, start[, end]])

   Like "rfind()" but raises "ValueError" when the substring *sub* is
   not found. For example:

      >>> 'spam, spam, spam'.rindex('spam')
      12
      >>> 'spam, spam, spam'.rindex('eggs')
      Traceback (most recent call last):
        File "<stdin-0>", line 1, in <module>
          'spam, spam, spam'.rindex('eggs')
          ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
      ValueError: substring not found

   See also "index()" and "find()".

str.rjust(width, fillchar=' ', /)

   Renvoie la chaîne justifiée à droite dans une chaîne de longueur
   *width*. Le bourrage est fait en utilisant le caractère spécifié
   par *fillchar* (par défaut une espace ASCII). La chaîne d'origine
   est renvoyée si *width* est inférieure ou égale à "len(s)".

str.rpartition(sep, /)

   Divise la chaîne à la dernière occurrence de *sep*, et renvoie un
   triplet contenant la partie avant le séparateur, le séparateur lui-
   même, et la partie après le séparateur. Si le séparateur n'est pas
   trouvé, le triplet contient deux chaînes vides, puis la chaîne
   elle-même.

   For example:

      >>> 'Monty Python'.rpartition(' ')
      ('Monty', ' ', 'Python')
      >>> "Monty Python's Flying Circus".rpartition(' ')
      ("Monty Python's Flying", ' ', 'Circus')
      >>> 'Monty Python'.rpartition('-')
      ('', '', 'Monty Python')

   See also "partition()".

str.rsplit(sep=None, maxsplit=-1)

   Renvoie une liste des mots de la chaîne, en utilisant *sep* comme
   séparateur. Si *maxsplit* est donné, c'est le nombre maximum de
   divisions qui pourront être faites, celles « les plus à droite ».
   Si *sep* est pas spécifié ou est "None", tout caractère
   d'espacement est un séparateur. En dehors du fait qu'il découpe par
   la droite, "rsplit()" se comporte comme "split()" qui est décrit en
   détail ci-dessous.

str.rstrip(chars=None, /)

   Return a copy of the string with trailing characters removed.  The
   *chars* argument is a string specifying the set of characters to be
   removed.  If omitted or "None", the *chars* argument defaults to
   removing whitespace.  The *chars* argument is not a suffix; rather,
   all combinations of its values are stripped. For example:

      >>> '   spacious   '.rstrip()
      '   spacious'
      >>> 'mississippi'.rstrip('ipz')
      'mississ'

   See "removesuffix()" for a method that will remove a single suffix
   string rather than all of a set of characters.  For example:

      >>> 'Monty Python'.rstrip(' Python')
      'M'
      >>> 'Monty Python'.removesuffix(' Python')
      'Monty'

   See also "strip()".

str.split(sep=None, maxsplit=-1)

   Renvoie une liste des mots de la chaîne, en utilisant *sep* comme
   séparateur de mots. Si *maxsplit* est donné, c'est le nombre
   maximum de divisions qui pourront être effectuées (donnant ainsi
   une liste de longueur "maxsplit+1"). Si *maxsplit* n'est pas
   fourni, ou vaut "-1", le nombre de découpes n'est pas limité
   (toutes les découpes possibles sont faites).

   If *sep* is given, consecutive delimiters are not grouped together
   and are deemed to delimit empty strings (for example,
   "'1,,2'.split(',')" returns "['1', '', '2']").  The *sep* argument
   may consist of multiple characters as a single delimiter (to split
   with multiple delimiters, use "re.split()"). Splitting an empty
   string with a specified separator returns "['']".

   Par exemple :

      >>> '1,2,3'.split(',')
      ['1', '2', '3']
      >>> '1,2,3'.split(',', maxsplit=1)
      ['1', '2,3']
      >>> '1,2,,3,'.split(',')
      ['1', '2', '', '3', '']
      >>> '1<>2<>3<4'.split('<>')
      ['1', '2', '3<4']

   Si *sep* n'est pas spécifié ou est "None", un autre algorithme de
   découpage est appliqué : les caractères d'espacement consécutifs
   sont considérés comme un seul séparateur, et le résultat ne
   contient pas les chaînes vides de début ou de la fin si la chaîne
   est préfixée ou suffixé de caractères d'espacement. Par conséquent,
   diviser une chaîne vide ou une chaîne composée d'espaces avec un
   séparateur "None" renvoie "[]".

   Par exemple :

      >>> '1 2 3'.split()
      ['1', '2', '3']
      >>> '1 2 3'.split(maxsplit=1)
      ['1', '2 3']
      >>> '   1   2   3   '.split()
      ['1', '2', '3']

   If *sep* is not specified or is "None" and  *maxsplit* is "0", only
   leading runs of consecutive whitespace are considered.

   Par exemple :

      >>> "".split(None, 0)
      []
      >>> "   ".split(None, 0)
      []
      >>> "   foo   ".split(maxsplit=0)
      ['foo   ']

   See also "join()".

str.splitlines(keepends=False)

   Renvoie les lignes de la chaîne sous forme de liste, la découpe se
   faisant au niveau des limites des lignes. Les sauts de ligne ne
   sont pas inclus dans la liste des résultats, sauf si *keepends* est
   donné et est vrai.

   Cette méthode découpe sur les limites de ligne suivantes. Ces
   limites sont un sur-ensemble de *universal newlines*.

   +-------------------------+-------------------------------+
   | Représentation          | Description                   |
   |=========================|===============================|
   | "\n"                    | Saut de ligne                 |
   +-------------------------+-------------------------------+
   | "\r"                    | Retour chariot                |
   +-------------------------+-------------------------------+
   | "\r\n"                  | Retour chariot + saut de      |
   |                         | ligne                         |
   +-------------------------+-------------------------------+
   | "\v" or "\x0b"          | Tabulation verticale          |
   +-------------------------+-------------------------------+
   | "\f" or "\x0c"          | Saut de page                  |
   +-------------------------+-------------------------------+
   | "\x1c"                  | Séparateur de fichiers        |
   +-------------------------+-------------------------------+
   | "\x1d"                  | Séparateur de groupes         |
   +-------------------------+-------------------------------+
   | "\x1e"                  | Séparateur d'enregistrements  |
   +-------------------------+-------------------------------+
   | "\x85"                  | Ligne suivante (code de       |
   |                         | contrôle *C1*)                |
   +-------------------------+-------------------------------+
   | "\u2028"                | Séparateur de ligne           |
   +-------------------------+-------------------------------+
   | "\u2029"                | Séparateur de paragraphe      |
   +-------------------------+-------------------------------+

   Modifié dans la version 3.2: "\v" et "\f" ajoutés à la liste des
   limites de lignes.

   Par exemple :

      >>> 'ab c\n\nde fg\rkl\r\n'.splitlines()
      ['ab c', '', 'de fg', 'kl']
      >>> 'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True)
      ['ab c\n', '\n', 'de fg\r', 'kl\r\n']

   Contrairement à "split()" lorsque *sep* est fourni, cette méthode
   renvoie une liste vide pour la chaîne vide, et un saut de ligne à
   la fin ne se traduit pas par une ligne supplémentaire :

      >>> "".splitlines()
      []
      >>> "One line\n".splitlines()
      ['One line']

   À titre de comparaison, "split('\n')" donne :

      >>> ''.split('\n')
      ['']
      >>> 'Two lines\n'.split('\n')
      ['Two lines', '']

str.startswith(prefix[, start[, end]])

   Renvoie "True" si la chaîne commence par *prefix*, sinon  "False".
   *prefix* peut aussi être un *n*-uplet de préfixes à rechercher.
   Lorsque *start* est donné, la comparaison commence à cette position
   et, lorsque *end* est donné, la comparaison s'arrête à celle-ci.

   For example:

      >>> 'Python'.startswith('Py')
      True
      >>> 'a tuple of prefixes'.startswith(('at', 'a'))
      True
      >>> 'Python is amazing'.startswith('is', 7)
      True

   See also "endswith()" and "removeprefix()".

str.strip(chars=None, /)

   Return a copy of the string with the leading and trailing
   characters removed. The *chars* argument is a string specifying the
   set of characters to be removed. If omitted or "None", the *chars*
   argument defaults to removing whitespace. The *chars* argument is
   not a prefix or suffix; rather, all combinations of its values are
   stripped.

   For example:

      >>> '   spacious   '.strip()
      'spacious'
      >>> 'www.example.com'.strip('cmowz.')
      'example'

   The outermost leading and trailing *chars* argument values are
   stripped from the string. Characters are removed from the leading
   end until reaching a string character that is not contained in the
   set of characters in *chars*. A similar action takes place on the
   trailing end.

   For example:

      >>> comment_string = '#....... Section 3.2.1 Issue #32 .......'
      >>> comment_string.strip('.#! ')
      'Section 3.2.1 Issue #32'

   See also "rstrip()".

str.swapcase()

   Renvoie une copie de la chaîne dont les caractères majuscules sont
   convertis en minuscules et vice versa. Notez qu'il est pas
   nécessairement vrai que "s.swapcase().swapcase() == s".

str.title()

   Renvoie une version de la chaîne où les mots commencent par une
   capitale et les caractères restants sont en minuscules.

   Par exemple :

      >>> 'Hello world'.title()
      'Hello World'

   Pour l'algorithme, la notion de mot est définie simplement et
   indépendamment de la langue comme un groupe de lettres
   consécutives. La définition fonctionne dans de nombreux contextes,
   mais cela signifie que les apostrophes (typiquement de la forme
   possessive en Anglais) forment les limites de mot, ce qui n'est pas
   toujours le résultat souhaité :

      >>> "they're bill's friends from the UK".title()
      "They'Re Bill'S Friends From The Uk"

   La fonction "string.capwords()" n'a pas ce problème, car elle
   sépare les mots uniquement sur les espaces.

   Sinon, une solution pour contourner le problème des apostrophes est
   d'utiliser des expressions rationnelles :

      >>> import re
      >>> def titlecase(s):
      ...     return re.sub(r"[A-Za-z]+('[A-Za-z]+)?",
      ...                   lambda mo: mo.group(0).capitalize(),
      ...                   s)
      ...
      >>> titlecase("they're bill's friends.")
      "They're Bill's Friends."

   See also "istitle()".

str.translate(table, /)

   Return a copy of the string in which each character has been mapped
   through the given translation table.  The table must be an object
   that implements indexing via "__getitem__()", typically a *mapping*
   or *sequence*.  When indexed by a Unicode ordinal (an integer), the
   table object can do any of the following: return a Unicode ordinal
   or a string, to map the character to one or more other characters;
   return "None", to delete the character from the return string; or
   raise a "LookupError" exception, to map the character to itself.

   Vous pouvez utiliser "str.maketrans()" pour créer une table de
   correspondances de caractères dans différents formats.

   Voir aussi le module "codecs" pour une approche plus souple de
   changements de caractères par correspondance.

str.upper()

   Renvoie une copie de la chaîne où tous les caractères
   capitalisables [4] ont été convertis en capitales. Notez que
   "s.upper().isupper()" peut être "False" si "s" contient des
   caractères non capitalisables ou si la catégorie Unicode d'un
   caractère du résultat n'est pas "Lu" (*Letter*, *uppercase*), mais
   par exemple "Lt" (*Letter*, *titlecase*).

   The uppercasing algorithm used is described in section 3.13
   'Default Case Folding' of the Unicode Standard.

str.zfill(width, /)

   Renvoie une copie de la chaîne remplie par la gauche du chiffre (le
   caractère ASCII) "'0'" pour faire une chaîne de longueur *width*.
   Un préfixe ("'+'" / "'-'") est permis par l'insertion du caractère
   de bourrage *après* le caractère désigné plutôt qu'avant. La chaîne
   d'origine est renvoyée si *width* est inférieure ou égale à
   "len(s)".

   Par exemple :

      >>> "42".zfill(5)
      '00042'
      >>> "-42".zfill(5)
      '-0042'


Formatted String Literals (f-strings)
-------------------------------------

Ajouté dans la version 3.6.

Modifié dans la version 3.7: The "await" and "async for" can be used
in expressions within f-strings.

Modifié dans la version 3.8: Added the debug specifier ("=")

Modifié dans la version 3.12: Many restrictions on expressions within
f-strings have been removed. Notably, nested strings, comments, and
backslashes are now permitted.

An *f-string* (formally a *formatted string literal*) is a string
literal that is prefixed with "f" or "F". This type of string literal
allows embedding the results of arbitrary Python expressions within
*replacement fields*, which are delimited by curly brackets ("{}").
Each replacement field must contain an expression, optionally followed
by:

* a *debug specifier* -- an equal sign ("=");

* a *conversion specifier* -- "!s", "!r" or "!a"; and/or

* a *format specifier* prefixed with a colon (":").

See the Lexical Analysis section on f-strings for details on the
syntax of these fields.


Debug specifier
~~~~~~~~~~~~~~~

Ajouté dans la version 3.8.

If a debug specifier -- an equal sign ("=") -- appears after the
replacement field expression, the resulting f-string will contain the
expression's source, the equal sign, and the value of the expression.
This is often useful for debugging:

   >>> number = 14.3
   >>> f'{number=}'
   'number=14.3'

Whitespace before, inside and after the expression, as well as
whitespace after the equal sign, is significant --- it is retained in
the result:

   >>> f'{ number  -  4  = }'
   ' number  -  4  = 10.3'


Conversion specifier
~~~~~~~~~~~~~~~~~~~~

By default, the value of a replacement field expression is converted
to a string using "str()":

   >>> from fractions import Fraction
   >>> one_third = Fraction(1, 3)
   >>> f'{one_third}'
   '1/3'

When a debug specifier but no format specifier is used, the default
conversion instead uses "repr()":

   >>> f'{one_third = }'
   'one_third = Fraction(1, 3)'

The conversion can be specified explicitly using one of these
specifiers:

* "!s" for "str()"

* "!r" for "repr()"

* "!a" for "ascii()"

Par exemple :

   >>> str(one_third)
   '1/3'
   >>> repr(one_third)
   'Fraction(1, 3)'

   >>> f'{one_third!s} is {one_third!r}'
   '1/3 is Fraction(1, 3)'

   >>> string = "¡kočka 😸!"
   >>> ascii(string)
   "'\\xa1ko\\u010dka \\U0001f638!'"

   >>> f'{string = !a}'
   "string = '\\xa1ko\\u010dka \\U0001f638!'"


Format specifier
~~~~~~~~~~~~~~~~

After the expression has been evaluated, and possibly converted using
an explicit conversion specifier, it is formatted using the "format()"
function. If the replacement field includes a *format specifier*
introduced by a colon (":"), the specifier is passed to "format()" as
the second argument. The result of "format()" is then used as the
final value for the replacement field. For example:

   >>> from fractions import Fraction
   >>> one_third = Fraction(1, 3)
   >>> f'{one_third:.6f}'
   '0.333333'
   >>> f'{one_third:_^+10}'
   '___+1/3___'
   >>> >>> f'{one_third!r:_^20}'
   '___Fraction(1, 3)___'
   >>> f'{one_third = :~>10}~'
   'one_third = ~~~~~~~1/3~'


Template String Literals (t-strings)
------------------------------------

An *t-string* (formally a *template string literal*) is a string
literal that is prefixed with "t" or "T".

These strings follow the same syntax and evaluation rules as formatted
string literals, with for the following differences:

* Rather than evaluating to a "str" object, template string literals
  evaluate to a "string.templatelib.Template" object.

* The "format()" protocol is not used. Instead, the format specifier
  and conversions (if any) are passed to a new "Interpolation" object
  that is created for each evaluated expression. It is up to code that
  processes the resulting "Template" object to decide how to handle
  format specifiers and conversions.

* Format specifiers containing nested replacement fields are evaluated
  eagerly, prior to being passed to the "Interpolation" object. For
  instance, an interpolation of the form "{amount:.{precision}f}" will
  evaluate the inner expression "{precision}" to determine the value
  of the "format_spec" attribute. If "precision" were to be "2", the
  resulting format specifier would be "'.2f'".

* When the equals sign "'='" is provided in an interpolation
  expression, the text of the expression is appended to the literal
  string that precedes the relevant interpolation. This includes the
  equals sign and any surrounding whitespace. The "Interpolation"
  instance for the expression will be created as normal, except that
  "conversion" will be set to '"r"' ("repr()") by default. If an
  explicit conversion or format specifier are provided, this will
  override the default behaviour.


Formatage de chaines à la "printf"
----------------------------------

Note:

  The formatting operations described here exhibit a variety of quirks
  that lead to a number of common errors (such as failing to display
  tuples and dictionaries correctly).Using formatted string literals,
  the "str.format()" interface, or "string.Template" may help avoid
  these errors. Each of these alternatives provides their own trade-
  offs and benefits of simplicity, flexibility, and/or extensibility.

String objects have one unique built-in operation: the "%" operator
(modulo). This is also known as the string *formatting* or
*interpolation* operator. Given "format % values" (where *format* is a
string), "%" conversion specifications in *format* are replaced with
zero or more elements of *values*. The effect is similar to using the
"sprintf()" function in the C language. For example:

   >>> print('%s has %d quote types.' % ('Python', 2))
   Python has 2 quote types.

Si *format* ne nécessite qu'un seul argument, *values* peut être un
objet unique [5]. Si *values* est un *n*-uplet, il doit contenir
exactement le nombre d'éléments spécifiés par la chaîne de format, ou
un seul objet tableau de correspondances (*mapping object*, par
exemple, un dictionnaire).

Un indicateur de conversion contient deux ou plusieurs caractères et
comporte les éléments suivants, qui doivent apparaître dans cet ordre
:

1. le caractère "'%'", qui marque le début du marqueur ;

2. la clé de correspondance (facultative), composée d'une suite de
   caractères entre parenthèses (par exemple, "(somename)") ;

3. des indications de conversion, facultatives, qui affectent le
   résultat de certains types de conversion ;

4. largeur minimum (facultative). Si elle vaut "'*'" (astérisque), la
   largeur est lue de l'élément suivant du *n*-uplet *values*, et
   l'objet à convertir vient après la largeur de champ minimale et la
   précision facultative ;

5. précision (facultatif), donnée sous la forme d'un "'.'" (point)
   suivi de la précision. Si la précision est "'*'" (un astérisque),
   la précision est lue à partir de l'élément suivant du *n*-uplet
   *values* et la valeur à convertir vient ensuite ;

6. modificateur de longueur (facultatif) ;

7. type de conversion.

Lorsque l'argument de droite est un dictionnaire (ou un autre type de
tableau de correspondances), les marqueurs dans la chaîne *doivent*
inclure une clé présente dans le dictionnaire, écrite entre
parenthèses,  immédiatement après le caractère "'%'". La clé indique
quelle valeur du dictionnaire doit être formatée. Par exemple :

>>> print('%(language)s has %(number)03d quote types.' %
...       {'language': "Python", "number": 2})
Python has 002 quote types.

Dans ce cas, aucune "*" ne peut se trouver dans le format (car ces "*"
nécessitent une liste (accès séquentiel) de paramètres).

Les caractères indicateurs de conversion sont :

+-----------+-----------------------------------------------------------------------+
| Option    | Signification                                                         |
|===========|=======================================================================|
| "'#'"     | La conversion utilise la « forme alternative » (définie ci-dessous).  |
+-----------+-----------------------------------------------------------------------+
| "'0'"     | Les valeurs numériques converties sont complétées de zéros.           |
+-----------+-----------------------------------------------------------------------+
| "'-'"     | La valeur convertie est ajustée à gauche (remplace la conversion      |
|           | "'0'" si les deux sont données).                                      |
+-----------+-----------------------------------------------------------------------+
| "' '"     | (une espace) Une espace doit être laissée avant un nombre positif (ou |
|           | chaîne vide) produite par la conversion d'une valeur signée.          |
+-----------+-----------------------------------------------------------------------+
| "'+'"     | Un caractère de signe ("'+'" ou "'-'") précède la valeur convertie    |
|           | (remplace le marqueur « espace »).                                    |
+-----------+-----------------------------------------------------------------------+

Un modificateur de longueur ("h", "l" ou "L") peut être présent, mais
est ignoré car il est pas nécessaire pour Python, donc par exemple
"%ld" est identique à "%d".

Les types utilisables dans les conversions sont :

+--------------+-------------------------------------------------------+---------+
| Conversion   | Signification                                         | Notes   |
|==============|=======================================================|=========|
| "'d'"        | Entier décimal signé.                                 |         |
+--------------+-------------------------------------------------------+---------+
| "'i'"        | Entier décimal signé.                                 |         |
+--------------+-------------------------------------------------------+---------+
| "'o'"        | Valeur octale signée.                                 | (1)     |
+--------------+-------------------------------------------------------+---------+
| "'u'"        | Type obsolète — identique à "'d'".                    | (6)     |
+--------------+-------------------------------------------------------+---------+
| "'x'"        | Hexadécimal signé (en minuscules).                    | (2)     |
+--------------+-------------------------------------------------------+---------+
| "'X'"        | Hexadécimal signé (capitales).                        | (2)     |
+--------------+-------------------------------------------------------+---------+
| "'e'"        | Floating-point exponential format (lowercase).        | (3)     |
+--------------+-------------------------------------------------------+---------+
| "'E'"        | Floating-point exponential format (uppercase).        | (3)     |
+--------------+-------------------------------------------------------+---------+
| "'f'"        | Floating-point decimal format.                        | (3)     |
+--------------+-------------------------------------------------------+---------+
| "'F'"        | Floating-point decimal format.                        | (3)     |
+--------------+-------------------------------------------------------+---------+
| "'g'"        | Floating-point format. Uses lowercase exponential     | (4)     |
|              | format if exponent is less than -4 or not less than   |         |
|              | precision, decimal format otherwise.                  |         |
+--------------+-------------------------------------------------------+---------+
| "'G'"        | Floating-point format. Uses uppercase exponential     | (4)     |
|              | format if exponent is less than -4 or not less than   |         |
|              | precision, decimal format otherwise.                  |         |
+--------------+-------------------------------------------------------+---------+
| "'c'"        | Un seul caractère (accepte des entiers ou une chaîne  |         |
|              | d'un seul caractère).                                 |         |
+--------------+-------------------------------------------------------+---------+
| "'r'"        | String (convertit n'importe quel objet Python avec    | (5)     |
|              | "repr()").                                            |         |
+--------------+-------------------------------------------------------+---------+
| "'s'"        | String (convertit n'importe quel objet Python avec    | (5)     |
|              | "str()").                                             |         |
+--------------+-------------------------------------------------------+---------+
| "'a'"        | String (convertit n'importe quel objet Python en      | (5)     |
|              | utilisant "ascii()").                                 |         |
+--------------+-------------------------------------------------------+---------+
| "'%'"        | Aucun argument n'est converti, donne un caractère de  |         |
|              | "'%'" dans le résultat.                               |         |
+--------------+-------------------------------------------------------+---------+

Notes :

1. La forme alternative entraîne l'insertion d'un préfixe octal
   ("'0o'") avant le premier chiffre.

2. La forme alternative entraîne l'insertion d'un préfixe "'0x'" ou
   "'0X'" (respectivement pour les formats "'x'" et "'X'") avant le
   premier chiffre.

3. La forme alternative implique la présence d'un point décimal, même
   si aucun chiffre ne le suit.

   La précision détermine le nombre de chiffres après la virgule, 6
   par défaut.

4. La forme alternative implique la présence d'un point décimal et les
   zéros non significatifs sont conservés (ils ne le seraient pas
   autrement).

   La précision détermine le nombre de chiffres significatifs avant et
   après la virgule. 6 par défaut.

5. Si la précision est "N", la sortie est tronquée à "N" caractères.

6. Voir la **PEP 237**.

Puisque les chaînes Python ont une longueur explicite, les conversions
"%s" ne considèrent pas "'\0'" comme la fin de la chaîne.

Modifié dans la version 3.1: les conversions "%f" des nombres dont la
valeur absolue est supérieure à "1e50" ne sont plus remplacées par des
conversions "%g".


Séquences Binaires — "bytes", "bytearray", "vue mémoire"
========================================================

Les principaux types natifs pour manipuler des données binaires sont
"bytes" et "bytearray". Ils sont gérés par les "vues mémoire" qui
utilisent le protocole tampon pour accéder à la mémoire d'autres
objets binaires sans avoir besoin d'en faire une copie.

Le module "array" permet le stockage efficace de types basiques comme
les entiers de 32 bits et les *float* double précision IEEE754.


Objets *bytes*
--------------

Les *bytes* sont des séquences immuables d'octets. Comme beaucoup de
protocoles binaires utilisent l'ASCII, les objets *bytes* offrent
plusieurs méthodes qui ne sont valables que lors de la manipulation de
données ASCII et sont étroitement liés aux objets *str* dans bien
d'autres aspects.

class bytes(source=b'')
class bytes(source, encoding, errors='strict')

   Tout d'abord, la syntaxe des *bytes* littéraux est en grande partie
   la même que pour les chaînes littérales, en dehors du préfixe "b" :

   * entre guillemets simples : "b'cela autorise les guillemets
     "doubles"'" ;

   * entre guillemets (anglais) : "b"cela permet aussi les guillemets
     'simples'"" ;

   * entre guillemets triples : "b'''3 single quotes'''", "b"""3
     double quotes"""".

   Seuls les caractères ASCII sont autorisés dans les littéraux de
   *bytes* (quel que soit l'encodage du code source déclaré). Toutes
   les valeurs au-delà de 127 doivent être écrites en utilisant une
   séquence d'échappement appropriée.

   Comme avec les chaînes littérales, les *bytes* littéraux peuvent
   également utiliser un préfixe "r" pour désactiver le traitement des
   séquences d'échappement. Voir Littéraux de chaînes de caractères et
   de suites d'octets pour plus d'informations sur les différentes
   formes littérales de *bytes*, y compris les séquences d'échappement
   gérées.

   Bien que les *bytes* littéraux, et leur représentation, soient
   basés sur du texte ASCII, les *bytes* se comportent en fait comme
   des séquences immuables de nombres entiers, dont les valeurs sont
   restreintes dans l'intervalle "0 <= x < 256" (ne pas respecter
   cette restriction lève une "ValueError"). C'est délibéré afin de
   souligner que, bien que de nombreux encodages binaires soient
   compatibles avec l'ASCII, et peuvent être manipulés avec des
   algorithmes orientés texte, ce n'est généralement pas le cas pour
   les données binaires arbitraires (appliquer aveuglément des
   algorithmes de texte sur des données binaires qui ne sont pas
   compatibles ASCII conduit généralement à leur corruption).

   En plus des formes littérales, des objets *bytes* peuvent être
   créés par de nombreux moyens :

   * un objet *bytes* rempli de zéros d'une longueur spécifiée :
     "bytes(10)" ;

   * un itérable d'entiers : "bytes(range(20))" ;

   * la copie de données binaires existantes via le protocole tampon :
     "bytes(obj)".

   Voir aussi la fonction native bytes.

   Puisque 2 chiffres hexadécimaux correspondent précisément à un seul
   octet, les nombres hexadécimaux sont un format couramment utilisé
   pour décrire les données binaires. Par conséquent, le type *bytes*
   a une méthode de classe pour lire des données dans ce format :

   classmethod fromhex(string, /)

      Cette méthode de la classe "bytes" renvoie un objet *bytes*,
      décodant la chaîne donnée.  La chaîne doit contenir deux
      chiffres hexadécimaux par octet, les espaces ASCII sont ignorés.

      >>> bytes.fromhex('2Ef0 F1f2  ')
      b'.\xf0\xf1\xf2'

      Modifié dans la version 3.7: "bytes.fromhex()" saute maintenant
      dans la chaîne tous les caractères ASCII d'espacement, pas
      seulement les espaces.

      Modifié dans la version 3.14: "bytes.fromhex()" now accepts
      ASCII "bytes" and *bytes-like objects* as input.

   Une fonction de conversion inverse existe pour transformer un objet
   *bytes* en sa représentation hexadécimale.

   hex(*, bytes_per_sep=1)
   hex(sep, bytes_per_sep=1)

      Renvoie une chaîne contenant deux chiffres hexadécimaux pour
      chaque octet de l'instance.

      >>> b'\xf0\xf1\xf2'.hex()
      'f0f1f2'

      Si vous voulez obtenir une chaîne hexadécimale plus facile à
      lire, vous pouvez spécifier le paramètre *sep* comme « caractère
      de séparation », à inclure dans la sortie. Par défaut, ce
      caractère est inséré entre chaque octet. Un second paramètre
      optionnel *bytes_per_sep* contrôle l'espacement. Les valeurs
      positives calculent la position du séparateur en partant de la
      droite, les valeurs négatives de la gauche.

      >>> value = b'\xf0\xf1\xf2'
      >>> value.hex('-')
      'f0-f1-f2'
      >>> value.hex('_', 2)
      'f0_f1f2'
      >>> b'UUDDLRLRAB'.hex(' ', -4)
      '55554444 4c524c52 4142'

      Ajouté dans la version 3.5.

      Modifié dans la version 3.8: "bytes.hex()" prend désormais en
      charge les paramètres optionnels *sep* et *bytes_per_sep* pour
      insérer des séparateurs entre les octets dans la sortie
      hexadécimale.

Comme les objets *bytes* sont des séquences d'entiers (semblables à un
*n*-uplet), pour une instance de *bytes* *b*, "b[0]" est un entier,
tandis que "b[0:1]" est un objet *bytes* de longueur 1. (Cela
contraste avec les chaînes, où un indice et le découpage donnent une
chaîne de longueur 1.)

La représentation des *bytes* utilise le format littéral ("b'...'")
car il est souvent plus utile que par exemple "bytes([46, 46, 46])".
Vous pouvez toujours convertir un *bytes* en liste d'entiers en
utilisant "list(b)".


Objets *bytearray*
------------------

Les objets "bytearray" sont l'équivalent mutable des objets "bytes".

class bytearray(source=b'')
class bytearray(source, encoding, errors='strict')

   Il n'y a pas de syntaxe littérale dédiée aux *bytearray*, ils sont
   toujours créés en appelant le constructeur :

   * créer une instance vide : "bytearray()" ;

   * crée une instance remplie de zéros d'une longueur donnée :
     "bytearray(10)" ;

   * à partir d'un itérable d'entiers : "bytearray(range(20))" ;

   * copie des données binaires existantes via le protocole tampon :
     "bytearray(b'Hi!')".

   Comme les *bytearray* sont mutables, ils prennent en charge les
   opérations de séquences mutables en plus des opérations communes de
   *bytes* et *bytearray* décrites dans Opérations sur les bytes et
   bytearray.

   Voir aussi la fonction native bytearray.

   Puisque 2 chiffres hexadécimaux correspondent précisément à un
   octet, les nombres hexadécimaux sont un format couramment utilisé
   pour décrire les données binaires. Par conséquent, le type
   *bytearray* a une méthode de classe pour lire les données dans ce
   format :

   classmethod fromhex(string, /)

      Cette méthode de la classe "bytearray" renvoie un objet
      *bytearray*, décodant la chaîne donnée.  La chaîne doit contenir
      deux chiffres hexadécimaux par octet, les caractères
      d'espacement ASCII sont ignorés.

      >>> bytearray.fromhex('2Ef0 F1f2  ')
      bytearray(b'.\xf0\xf1\xf2')

      Modifié dans la version 3.7: "bytearray.fromhex()" saute
      maintenant tous les caractères d'espacement ASCII dans la
      chaîne, pas seulement les espaces.

      Modifié dans la version 3.14: "bytearray.fromhex()" now accepts
      ASCII "bytes" and *bytes-like objects* as input.

   Une fonction de conversion inverse existe pour transformer un objet
   *bytearray* en sa représentation hexadécimale.

   hex(*, bytes_per_sep=1)
   hex(sep, bytes_per_sep=1)

      Renvoie une chaîne contenant deux chiffres hexadécimaux pour
      chaque octet de l'instance.

      >>> bytearray(b'\xf0\xf1\xf2').hex()
      'f0f1f2'

      Ajouté dans la version 3.5.

      Modifié dans la version 3.8: similaire à "bytes.hex()",
      "bytearray.hex()" prend désormais en charge les paramètres
      optionnels *sep* et *bytes_per_sep* pour insérer des séparateurs
      entre les octets dans la sortie hexadécimale.

   resize(size, /)

      Resize the "bytearray" to contain *size* bytes. *size* must be
      greater than or equal to 0.

      If the "bytearray" needs to shrink, bytes beyond *size* are
      truncated.

      If the "bytearray" needs to grow, all new bytes, those beyond
      *size*, will be set to null bytes.

      This is equivalent to:

      >>> def resize(ba, size):
      ...     if len(ba) > size:
      ...         del ba[size:]
      ...     else:
      ...         ba += b'\0' * (size - len(ba))

      Examples:

      >>> shrink = bytearray(b'abc')
      >>> shrink.resize(1)
      >>> (shrink, len(shrink))
      (bytearray(b'a'), 1)
      >>> grow = bytearray(b'abc')
      >>> grow.resize(5)
      >>> (grow, len(grow))
      (bytearray(b'abc\x00\x00'), 5)

      Ajouté dans la version 3.14.

Comme les *bytearray* sont des séquences d'entiers (semblables à une
liste), pour un objet *bytearray* *b*, "b[0]" est un entier, tandis
que "b[0:1]" est un objet *bytearray* de longueur 1. (Ceci contraste
avec les chaînes de texte, où l'indice et le découpage produisent une
chaîne de longueur 1)

La représentation des objets *bytearray* utilise le format littéral
des *bytes* ("bytearray(b'...')") car il est souvent plus utile que
par exemple "bytearray([46, 46, 46])". Vous pouvez toujours convertir
un objet *bytearray* en une liste de nombres entiers en utilisant
"list(b)".


Opérations sur les *bytes* et *bytearray*
-----------------------------------------

*bytes* et *bytearray* prennent en charge les opérations communes des
séquences. Ils interagissent non seulement avec des opérandes de même
type, mais aussi avec les *objets octet-compatibles*. En raison de
cette flexibilité, ils peuvent être mélangés librement dans des
opérations sans provoquer d'erreurs. Cependant, le type du résultat
peut dépendre de l'ordre des opérandes.

Note:

  les méthodes sur les *bytes* et les *bytearray* n'acceptent pas les
  chaînes comme arguments, tout comme les méthodes sur les chaînes
  n'acceptent pas les *bytes* comme arguments. Par exemple, vous devez
  écrire :

     a = "abc"
     b = a.replace("a", "f")

  et :

     a = b"abc"
     b = a.replace(b"a", b"f")

Quelques opérations de *bytes* et *bytesarray* supposent l'utilisation
de formats binaires compatibles ASCII, et donc doivent être évités
lorsque vous travaillez avec des données binaires arbitraires. Ces
restrictions sont couvertes ci-dessous.

Note:

  utiliser ces opérations basées sur l'ASCII pour manipuler des
  données binaires qui ne sont pas au format ASCII peut les corrompre.

Les méthodes suivantes sur les *bytes* et *bytearray* peuvent être
utilisées avec des données binaires arbitraires.

bytes.count(sub[, start[, end]])
bytearray.count(sub[, start[, end]])

   Renvoie le nombre d'occurrences qui ne se chevauchent pas de la
   sous-séquence *sub* dans l'intervalle [*start*, *end*]. Les
   arguments facultatifs *start* et *end* sont interprétés comme dans
   la notation des découpages.

   La sous-séquence à rechercher peut être un quelconque *objet octet-
   compatible* ou un nombre entier compris entre 0 et 255.

   Si *sub* est vide, renvoie le nombre de tranches vides entre les
   caractères de début et de fin, ce qui correspond à la longueur de
   l'objet bytes plus un.

   Modifié dans la version 3.3: accepte aussi un nombre entier compris
   entre 0 et 255 comme sous-séquence.

bytes.removeprefix(prefix, /)
bytearray.removeprefix(prefix, /)

   Si les données binaires commencent par la chaîne *prefix*, renvoie
   "bytes[len(prefix):]". Sinon, renvoie une copie des données
   binaires d'origine :

      >>> b'TestHook'.removeprefix(b'Test')
      b'Hook'
      >>> b'BaseTestCase'.removeprefix(b'Test')
      b'BaseTestCase'

   Le *prefix* peut être n'importe quel *objet octet-compatible*.

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

   Ajouté dans la version 3.9.

bytes.removesuffix(suffix, /)
bytearray.removesuffix(suffix, /)

   Si les données binaires terminent par la chaîne *suffix*, renvoie
   "bytes[:-len(suffix)]". Sinon, renvoie une copie des données
   binaires d'origine :

      >>> b'MiscTests'.removesuffix(b'Tests')
      b'Misc'
      >>> b'TmpDirMixin'.removesuffix(b'Tests')
      b'TmpDirMixin'

   Le *suffix* peut être n'importe quel *objet octet-compatible*.

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

   Ajouté dans la version 3.9.

bytes.decode(encoding='utf-8', errors='strict')
bytearray.decode(encoding='utf-8', errors='strict')

   Renvoie la chaine d'octets décodée en instance de "str".

   *encoding* vaut par défaut "utf-8" ; pour une liste des encodages
   possibles, voir la section Standard Encodings.

   *errors* détermine la manière dont sont traitées les erreurs. Sa
   valeur par défaut est "'strict'", ce qui signifie que les erreurs
   d'encodage lèvent une "UnicodeError". Les autres valeurs possibles
   sont "'ignore'", "'replace'" et tout autre nom enregistré *via*
   "codecs.register_error()", voir la section Gestionnaires d'erreurs
   pour les détails.

   Pour des raisons de performances, la valeur de *errors* n'est pas
   vérifiée à moins qu'une erreur de décodage ne se produise
   réellement, que le mode développeur ne soit activé ou que Python
   ait été compilé en mode débogage.

   Note:

     passer l'argument *encoding* à "str" permet de décoder tout
     *objet octet-compatible* directement, sans avoir besoin
     d'utiliser un "bytes" ou "bytearray" temporaire.

   Modifié dans la version 3.1: gère les arguments nommés.

   Modifié dans la version 3.9: les valeurs de *errors* sont
   maintenant vérifiées en mode de développement et en mode de
   débogage.

bytes.endswith(suffix[, start[, end]])
bytearray.endswith(suffix[, start[, end]])

   Renvoie "True" si les octets se terminent par *suffix*, sinon
   "False". *suffix* peut aussi être un *n*-uplet de suffixes à
   rechercher. Avec l'argument optionnel *start*, la recherche se fait
   à partir de cette position. Avec l'argument optionnel *end*, la
   comparaison s'arrête à cette position.

   Les suffixes à rechercher peuvent être n'importe quel *objet octet-
   compatible*.

bytes.find(sub[, start[, end]])
bytearray.find(sub[, start[, end]])

   Renvoie la première position où le *sub* se trouve dans les
   données,  de telle sorte que *sub* soit contenue dans
   "s[start:end]". Les arguments facultatifs *start* et *end* sont
   interprétés comme dans la notation des découpages. Renvoie "-1" si
   *sub* n'est pas trouvé.

   La sous-séquence à rechercher peut être un quelconque *objet octet-
   compatible* ou un nombre entier compris entre 0 et 255.

   Note:

     la méthode "find()" ne doit être utilisée que si vous avez besoin
     de connaître la position de *sub*. Pour vérifier si *sub* est
     présent ou non, utilisez l'opérateur "in" :

        >>> b'Py' in b'Python'
        True

   Modifié dans la version 3.3: accepte aussi un nombre entier compris
   entre 0 et 255 comme sous-séquence.

bytes.index(sub[, start[, end]])
bytearray.index(sub[, start[, end]])

   Comme "find()", mais lève une "ValueError" lorsque la séquence est
   introuvable.

   La sous-séquence à rechercher peut être un quelconque *objet octet-
   compatible* ou un nombre entier compris entre 0 et 255.

   Modifié dans la version 3.3: accepte aussi un nombre entier compris
   entre 0 et 255 comme sous-séquence.

bytes.join(iterable, /)
bytearray.join(iterable, /)

   Renvoie un *bytes* ou *bytearray* qui est la concaténation des
   séquences de données binaires dans *iterable*.  Une exception
   "TypeError" est levée si une valeur d'*iterable* n'est pas un
   *objet octet-compatible*, y compris pour des "str". Le séparateur
   entre les éléments est le contenu du *bytes* ou du *bytearray*
   depuis lequel cette méthode est appelée.

static bytes.maketrans(from, to, /)
static bytearray.maketrans(from, to, /)

   Cette méthode statique renvoie une table de traduction utilisable
   par "bytes.translate()" qui permettra de changer chaque caractère
   de *from* par un caractère à la même position dans *to* ; *from* et
   *to* doivent tous deux être des *objets octet-compatibles* et avoir
   la même longueur.

   Ajouté dans la version 3.1.

bytes.partition(sep, /)
bytearray.partition(sep, /)

   Divise la séquence à la première occurrence de *sep*, et renvoie un
   triplet contenant la partie précédant le séparateur, le séparateur
   lui-même (ou sa copie en *byterray*), et la partie suivant le
   séparateur. Si le séparateur n'est pas trouvé, le triplet renvoyé
   contient une copie de la séquence d'origine, suivi de deux *bytes*
   ou *bytearray* vides.

   Le séparateur à rechercher peut être tout *objet octet-compatible*.

bytes.replace(old, new, count=-1, /)
bytearray.replace(old, new, count=-1, /)

   Renvoie une copie de la séquence dont toutes les occurrences de la
   sous-séquence *old* sont remplacées par *new*. Si l'argument
   optionnel *count* est donné, seules les *count* premières
   occurrences sont remplacées.

   La sous-séquence à rechercher et son remplacement peuvent être
   n'importe quel *objet octet-compatible*.

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

bytes.rfind(sub[, start[, end]])
bytearray.rfind(sub[, start[, end]])

   Renvoie la plus grande position de *sub* dans la séquence, de telle
   sorte que *sub* soit dans "s[start:end]". Les arguments facultatifs
   *start* et *end* sont interprétés comme dans la notation des
   découpages. Renvoie "-1" si *sub* n'est pas trouvable.

   La sous-séquence à rechercher peut être un quelconque *objet octet-
   compatible* ou un nombre entier compris entre 0 et 255.

   Modifié dans la version 3.3: accepte aussi un nombre entier compris
   entre 0 et 255 comme sous-séquence.

bytes.rindex(sub[, start[, end]])
bytearray.rindex(sub[, start[, end]])

   Semblable à "rfind()" mais lève une "ValueError" lorsque *sub* est
   introuvable.

   La sous-séquence à rechercher peut être un quelconque *objet octet-
   compatible* ou un nombre entier compris entre 0 et 255.

   Modifié dans la version 3.3: accepte aussi un nombre entier compris
   entre 0 et 255 comme sous-séquence.

bytes.rpartition(sep, /)
bytearray.rpartition(sep, /)

   Coupe la séquence à la dernière occurrence de *sep*, et renvoie un
   triplet de trois éléments contenant la partie précédant le
   séparateur, le séparateur lui-même (ou sa copie, un *bytearray*),
   et la partie suivant le séparateur. Si le séparateur n'est pas
   trouvé, le triplet contient deux *bytes* ou *bytesarray* vides
   suivi d’une copie de la séquence d'origine.

   Le séparateur à rechercher peut être tout *objet octet-compatible*.

bytes.startswith(prefix[, start[, end]])
bytearray.startswith(prefix[, start[, end]])

   Renvoie "True" si les données binaires commencent par le *prefix*
   spécifié, sinon "False". *prefix* peut aussi être un *n*-uplet de
   préfixes à rechercher. Avec l'argument *start* la recherche
   commence à cette position. Avec l'argument *end* option, la
   recherche s'arrête à cette position.

   Les préfixes à rechercher peuvent être n'importe quels *objets
   octet-compatibles*.

bytes.translate(table, /, delete=b'')
bytearray.translate(table, /, delete=b'')

   Renvoie une copie du *bytes* ou *bytearray* dont tous les octets de
   *delete* sont supprimés, et les octets restants changés par la
   table de correspondance donnée, qui doit être un objet *bytes*
   d'une longueur de 256.

   Vous pouvez utiliser la méthode "bytes.maketrans()" pour créer une
   table de correspondance.

   Donnez "None" comme *table* pour seulement supprimer des caractères
   :

      >>> b'read this short text'.translate(None, b'aeiou')
      b'rd ths shrt txt'

   Modifié dans la version 3.6: *delete* est maintenant accepté comme
   argument nommé.

Les méthodes suivantes sur les *bytes* et *bytearray* supposent par
défaut que les données traitées sont compatibles ASCII, mais peuvent
toujours être utilisées avec des données binaires, arbitraires, en
passant des arguments appropriés. Notez que toutes les méthodes de
*bytearray* de cette section ne travaillent jamais sur l'objet lui-
même, mais renvoient un nouvel objet.

bytes.center(width, fillbyte=b' ', /)
bytearray.center(width, fillbyte=b' ', /)

   Renvoie une copie de l'objet centrée dans une séquence de longueur
   *width*. Le remplissage est fait en utilisant *fillbyte* (qui par
   défaut est une espace ASCII). Pour les objets "bytes", la séquence
   initiale est renvoyée si *width* est inférieure ou égale à
   "len(s)".

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

bytes.ljust(width, fillbyte=b' ', /)
bytearray.ljust(width, fillbyte=b' ', /)

   Renvoie une copie de l'objet aligné à gauche dans une séquence de
   longueur *width*. Le remplissage est fait en utilisant *fillbyte*
   (par défaut un espace ASCII). Pour les objets "bytes", la séquence
   initiale est renvoyée si *width* est inférieure ou égale à
   "len(s)".

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

bytes.lstrip(bytes=None, /)
bytearray.lstrip(bytes=None, /)

   Return a copy of the sequence with specified leading bytes removed.
   The *bytes* argument is a binary sequence specifying the set of
   byte values to be removed.  If omitted or "None", the *bytes*
   argument defaults to removing ASCII whitespace.  The *bytes*
   argument is not a prefix; rather, all combinations of its values
   are stripped:

      >>> b'   spacious   '.lstrip()
      b'spacious   '
      >>> b'www.example.com'.lstrip(b'cmowz.')
      b'example.com'

   Les octets à retirer peuvent être n'importe quel *bytes-like
   object*. Voir "removeprefix()" pour une méthode qui supprime, au
   début de la séquence, la chaîne de caractères en tant que telle
   plutôt que l'ensemble des caractères passés en paramètre. Par
   exemple :

      >>> b'Arthur: three!'.lstrip(b'Arthur: ')
      b'ee!'
      >>> b'Arthur: three!'.removeprefix(b'Arthur: ')
      b'three!'

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

bytes.rjust(width, fillbyte=b' ', /)
bytearray.rjust(width, fillbyte=b' ', /)

   Renvoie une copie de l'objet justifié à droite dans une séquence de
   longueur *width*. Le remplissage est fait en utilisant le caractère
   *fillbyte* (par défaut est un espace ASCII). Pour les objets
   "bytes", la séquence d'origine est renvoyée si *width* est
   inférieure ou égale à "len(s)".

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

bytes.rsplit(sep=None, maxsplit=-1)
bytearray.rsplit(sep=None, maxsplit=-1)

   Divise la séquence d'octets en sous-séquences du même type, en
   utilisant *sep* comme séparateur. Si *maxsplit* est donné, c'est le
   nombre maximum de divisions qui pourront être faites, celles "à
   droite". Si *sep* est pas spécifié ou est "None", toute sous-
   séquence composée uniquement d'espaces ASCII est un séparateur. En
   dehors du fait qu'il découpe par la droite, "rsplit()" se comporte
   comme "split()" qui est décrit en détail ci-dessous.

bytes.rstrip(bytes=None, /)
bytearray.rstrip(bytes=None, /)

   Return a copy of the sequence with specified trailing bytes
   removed.  The *bytes* argument is a binary sequence specifying the
   set of byte values to be removed.  If omitted or "None", the
   *bytes* argument defaults to removing ASCII whitespace.  The
   *bytes* argument is not a suffix; rather, all combinations of its
   values are stripped:

      >>> b'   spacious   '.rstrip()
      b'   spacious'
      >>> b'mississippi'.rstrip(b'ipz')
      b'mississ'

   Les octets à retirer peuvent être n'importe quel *bytes-like
   object*. Voir "removesuffix()" pour une méthode qui supprime, à la
   fin de la séquence, la chaîne de caractères en tant que telle
   plutôt que l'ensemble des caractères passés en paramètre. Par
   exemple :

      >>> b'Monty Python'.rstrip(b' Python')
      b'M'
      >>> b'Monty Python'.removesuffix(b' Python')
      b'Monty'

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

bytes.split(sep=None, maxsplit=-1)
bytearray.split(sep=None, maxsplit=-1)

   Divise la séquence en sous-séquences du même type, en utilisant
   *sep* comme séparateur. Si *maxsplit* est donné, c'est le nombre
   maximum de divisions qui pourront être faites (la liste aura donc
   au plus "maxsplit+1" éléments), Si *maxsplit* n'est pas spécifié ou
   faut "-1", il n'y a aucune limite au nombre de découpes (elles sont
   toutes effectuées).

   If *sep* is given, consecutive delimiters are not grouped together
   and are deemed to delimit empty subsequences (for example,
   "b'1,,2'.split(b',')" returns "[b'1', b'', b'2']").  The *sep*
   argument may consist of a multibyte sequence as a single delimiter.
   Splitting an empty sequence with a specified separator returns
   "[b'']" or "[bytearray(b'')]" depending on the type of object being
   split.  The *sep* argument may be any *bytes-like object*.

   Par exemple :

      >>> b'1,2,3'.split(b',')
      [b'1', b'2', b'3']
      >>> b'1,2,3'.split(b',', maxsplit=1)
      [b'1', b'2,3']
      >>> b'1,2,,3,'.split(b',')
      [b'1', b'2', b'', b'3', b'']
      >>> b'1<>2<>3<4'.split(b'<>')
      [b'1', b'2', b'3<4']

   Si *sep* n'est pas spécifié ou est "None", un autre algorithme de
   découpe est appliqué : les espaces ASCII consécutifs sont
   considérés comme un seul séparateur, et le résultat ne contiendra
   pas les chaînes vides de début ou de la fin si la chaîne est
   préfixée ou suffixé d'espaces. Par conséquent, diviser une séquence
   vide ou une séquence composée d'espaces ASCII avec un séparateur
   "None" renvoie "[]".

   Par exemple :

      >>> b'1 2 3'.split()
      [b'1', b'2', b'3']
      >>> b'1 2 3'.split(maxsplit=1)
      [b'1', b'2 3']
      >>> b'   1   2   3   '.split()
      [b'1', b'2', b'3']

bytes.strip(bytes=None, /)
bytearray.strip(bytes=None, /)

   Return a copy of the sequence with specified leading and trailing
   bytes removed. The *bytes* argument is a binary sequence specifying
   the set of byte values to be removed.  If omitted or "None", the
   *bytes* argument defaults to removing ASCII whitespace. The *bytes*
   argument is not a prefix or suffix; rather, all combinations of its
   values are stripped:

      >>> b'   spacious   '.strip()
      b'spacious'
      >>> b'www.example.com'.strip(b'cmowz.')
      b'example'

   Les octets à retirer peuvent être tout *bytes-like object*.

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

Les méthodes suivantes sur les *bytes* et *bytearray* supposent
l'utilisation d'un format binaire compatible ASCII, et donc doivent
être évités lorsque vous travaillez avec des données binaires
arbitraires. Notez que toutes les méthodes de *bytearray* de cette
section *ne modifient pas* les octets, ils produisent de nouveaux
objets.

bytes.capitalize()
bytearray.capitalize()

   Renvoie une copie de la séquence dont chaque octet est interprété
   comme un caractère ASCII, le premier octet en capitale et le reste
   en minuscules. Les octets non ASCII ne sont pas modifiés.

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

bytes.expandtabs(tabsize=8)
bytearray.expandtabs(tabsize=8)

   Renvoie une copie de la séquence où toutes les tabulations ASCII
   sont remplacées par un ou plusieurs espaces ASCII, en fonction de
   la colonne courante et de la taille de tabulation donnée. Les
   positions des tabulations se trouvent tous les *tabsize* caractères
   (8 par défaut, ce qui donne les positions de tabulations aux
   colonnes 0, 8, 16 et ainsi de suite). Pour travailler sur la
   séquence, la colonne en cours est mise à zéro et la séquence est
   examinée octets par octets. Si l'octet est une tabulation ASCII
   ("b'\t'"), un ou plusieurs espaces sont insérés au résultat jusqu’à
   ce que la colonne courante soit égale à la position de tabulation
   suivante. (Le caractère tabulation lui-même n’est pas copié.) Si
   l'octet courant est un saut de ligne ASCII ("b'\n'") ou un retour
   chariot ("b'\r'"), il est copié et la colonne en cours est remise à
   zéro. Tout autre octet est copié inchangé et la colonne en cours
   est incrémentée de un indépendamment de la façon dont l'octet est
   représenté lors de l’affichage :

      >>> b'01\t012\t0123\t01234'.expandtabs()
      b'01      012     0123    01234'
      >>> b'01\t012\t0123\t01234'.expandtabs(4)
      b'01  012 0123    01234'

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

bytes.isalnum()
bytearray.isalnum()

   Renvoie "True" si tous les caractères de la chaîne sont des
   caractères ASCII alphabétiques ou chiffres et que la séquence n'est
   pas vide, sinon "False". Les caractères ASCII alphabétiques sont
   les suivants dans la séquence d'octets
   "b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'" et les
   chiffres : "b'0123456789'".

   Par exemple :

      >>> b'ABCabc1'.isalnum()
      True
      >>> b'ABC abc1'.isalnum()
      False

bytes.isalpha()
bytearray.isalpha()

   Renvoie "True" si tous les octets dans la séquence sont des
   caractères alphabétiques ASCII et que la séquence n'est pas vide,
   sinon "False". Les caractères ASCII alphabétiques sont :
   "b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'".

   Par exemple :

      >>> b'ABCabc'.isalpha()
      True
      >>> b'ABCabc1'.isalpha()
      False

bytes.isascii()
bytearray.isascii()

   Renvoie "True" si la séquence est vide, ou si tous ses octets sont
   des octets ASCII, renvoie "False" dans le cas contraire. Les octets
   ASCII dans l'intervalle "0"–"0x7F".

   Ajouté dans la version 3.7.

bytes.isdigit()
bytearray.isdigit()

   Renvoie "True" si tous les octets de la séquence sont des chiffres
   ASCII et que la séquence n'est pas vide, sinon "False". Les
   chiffres ASCII sont ceux dans la séquence d'octets "b'0123456789'".

   Par exemple :

      >>> b'1234'.isdigit()
      True
      >>> b'1.23'.isdigit()
      False

bytes.islower()
bytearray.islower()

   Renvoie "True" s'il y a au moins un caractère ASCII minuscule dans
   la séquence et aucune capitale, sinon "False".

   Par exemple :

      >>> b'hello world'.islower()
      True
      >>> b'Hello world'.islower()
      False

   Les caractères ASCII minuscules sont
   "b'abcdefghijklmnopqrstuvwxyz'". Les capitales ASCII sont
   "b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'".

bytes.isspace()
bytearray.isspace()

   Renvoie "True" si tous les octets de la séquence sont des espaces
   ASCII et que la séquence n'est pas vide, sinon "False". Les espèces
   ASCII sont "b' \t\n\r\x0b\f'" (espace, tabulation, saut de ligne,
   retour chariot, tabulation verticale, saut de page).

bytes.istitle()
bytearray.istitle()

   Renvoie "True" si la séquence ASCII est *titlecased*, et qu'elle
   n'est pas vide, sinon "False". Voir "bytes.title()" pour plus de
   détails sur la définition de *titlecase*.

   Par exemple :

      >>> b'Hello World'.istitle()
      True
      >>> b'Hello world'.istitle()
      False

bytes.isupper()
bytearray.isupper()

   Renvoie "True" s'il y a au moins un caractère alphabétique
   majuscule ASCII dans la séquence et aucun caractère ASCII
   minuscule, sinon "False".

   Par exemple :

      >>> b'HELLO WORLD'.isupper()
      True
      >>> b'Hello world'.isupper()
      False

   Les caractères ASCII minuscules sont
   "b'abcdefghijklmnopqrstuvwxyz'". Les capitales ASCII sont
   "b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'".

bytes.lower()
bytearray.lower()

   Renvoie une copie de la séquence dont tous les caractères ASCII en
   majuscules sont convertis en leur équivalent en minuscules.

   Par exemple :

      >>> b'Hello World'.lower()
      b'hello world'

   Les caractères ASCII minuscules sont
   "b'abcdefghijklmnopqrstuvwxyz'". Les capitales ASCII sont
   "b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'".

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

bytes.splitlines(keepends=False)
bytearray.splitlines(keepends=False)

   Renvoie une liste des lignes de la séquence d'octets, découpant au
   niveau des fin de lignes ASCII. Cette méthode utilise l'approche
   *universal newlines* pour découper les lignes. Les fins de ligne ne
   sont pas inclus dans la liste des résultats, sauf si *keepends* est
   donné et vrai.

   Par exemple :

      >>> b'ab c\n\nde fg\rkl\r\n'.splitlines()
      [b'ab c', b'', b'de fg', b'kl']
      >>> b'ab c\n\nde fg\rkl\r\n'.splitlines(keepends=True)
      [b'ab c\n', b'\n', b'de fg\r', b'kl\r\n']

   Contrairement à "split()" lorsque le délimiteur *sep* est fourni,
   cette méthode renvoie une liste vide pour la chaîne vide, et un
   saut de ligne à la fin ne se traduit pas par une ligne
   supplémentaire :

      >>> b"".split(b'\n'), b"Two lines\n".split(b'\n')
      ([b''], [b'Two lines', b''])
      >>> b"".splitlines(), b"One line\n".splitlines()
      ([], [b'One line'])

bytes.swapcase()
bytearray.swapcase()

   Renvoie une copie de la séquence dont tous les caractères ASCII
   minuscules sont convertis en majuscules et vice-versa.

   Par exemple :

      >>> b'Hello World'.swapcase()
      b'hELLO wORLD'

   Les caractères ASCII minuscules sont
   "b'abcdefghijklmnopqrstuvwxyz'". Les capitales ASCII sont
   "b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'".

   Unlike "str.swapcase()", it is always the case that
   "bin.swapcase().swapcase() == bin" for the binary versions. Case
   conversions are symmetrical in ASCII, even though that is not
   generally true for arbitrary Unicode code points.

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

bytes.title()
bytearray.title()

   Renvoie une version *titlecased* de la séquence d'octets où les
   mots commencent par un caractère ASCII majuscule et les caractères
   restants sont en minuscules. Les octets non capitalisables ne sont
   pas modifiés.

   Par exemple :

      >>> b'Hello world'.title()
      b'Hello World'

   Les caractères ASCII minuscules sont
   "b'abcdefghijklmnopqrstuvwxyz'". Les caractères ASCII majuscules
   sont "b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'". Aucun autre octet n'est
   capitalisable.

   Pour l'algorithme, la notion de mot est définie simplement et
   indépendamment de la langue comme un groupe de lettres
   consécutives. La définition fonctionne dans de nombreux contextes,
   mais cela signifie que les apostrophes (typiquement de la forme
   possessive en Anglais) forment les limites de mot, ce qui n'est pas
   toujours le résultat souhaité :

      >>> b"they're bill's friends from the UK".title()
      b"They'Re Bill'S Friends From The Uk"

   Une solution pour contourner le problème des apostrophes peut être
   obtenue en utilisant des expressions rationnelles :

      >>> import re
      >>> def titlecase(s):
      ...     return re.sub(rb"[A-Za-z]+('[A-Za-z]+)?",
      ...                   lambda mo: mo.group(0)[0:1].upper() +
      ...                              mo.group(0)[1:].lower(),
      ...                   s)
      ...
      >>> titlecase(b"they're bill's friends.")
      b"They're Bill's Friends."

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

bytes.upper()
bytearray.upper()

   Renvoie une copie de la séquence dont tous les caractères ASCII
   minuscules sont convertis en leur équivalent majuscule.

   Par exemple :

      >>> b'Hello World'.upper()
      b'HELLO WORLD'

   Les caractères ASCII minuscules sont
   "b'abcdefghijklmnopqrstuvwxyz'". Les capitales ASCII sont
   "b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'".

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.

bytes.zfill(width, /)
bytearray.zfill(width, /)

   Renvoie une copie de la séquence remplie par la gauche du chiffre
   "b'0'" pour en faire une séquence de longueur *width*. Un préfixe
   ("b'+'" / "b'-'") est permis par l'insertion du caractère de
   remplissage *après* le caractère de signe plutôt qu'avant. Pour les
   objets "bytes" la séquence d'origine est renvoyée si *width* est
   inférieur ou égale à "len(seq)".

   Par exemple :

      >>> b"42".zfill(5)
      b'00042'
      >>> b"-42".zfill(5)
      b'-0042'

   Note:

     la version *bytearray* de cette méthode *ne modifie pas* les
     octets,  elle produit toujours un nouvel objet, même si aucune
     modification n'a été effectuée.


Formatage de *bytes* a la "printf"
----------------------------------

Note:

  Les opérations de formatage décrites ici présentent une variété de
  bizarreries qui conduisent à un certain nombre d’erreurs classiques
  (typiquement, échouer à afficher des *n*-uplets ou des dictionnaires
  correctement). Si la valeur à afficher peut être un *n*-uplet ou un
  dictionnaire, mettez-le à l'intérieur d'un autre *n*-uplet.

Les objets *bytes* ("bytes" et "bytearray") ont un unique opérateur :
l'opérateur "%" (modulo). Il est aussi connu sous le nom d'opérateur
de mise en forme. Avec "format % values" (où *format* est un objet
*bytes*), les marqueurs de conversion "%" dans *format* sont remplacés
par zéro ou plus de *values*. L'effet est similaire à la fonction
"sprintf()" du langage C.

Si *format* ne nécessite qu'un seul argument, *values* peut être un
objet unique. [5] Si *values* est un *n*-uplet, il doit contenir
exactement le nombre d'éléments spécifiés dans le format en *bytes*,
ou un seul objet de correspondances (*mapping object*, par exemple, un
dictionnaire).

Un indicateur de conversion contient deux ou plusieurs caractères et
comporte les éléments suivants, qui doivent apparaître dans cet ordre
:

1. le caractère "'%'", qui marque le début du marqueur ;

2. la clé de correspondance (facultative), composée d'une suite de
   caractères entre parenthèses (par exemple, "(somename)") ;

3. des indications de conversion, facultatives, qui affectent le
   résultat de certains types de conversion ;

4. largeur minimum (facultative). Si elle vaut "'*'" (astérisque), la
   largeur est lue de l'élément suivant du *n*-uplet *values*, et
   l'objet à convertir vient après la largeur de champ minimale et la
   précision facultative ;

5. précision (facultatif), donnée sous la forme d'un "'.'" (point)
   suivi de la précision. Si la précision est "'*'" (un astérisque),
   la précision est lue à partir de l'élément suivant du *n*-uplet
   *values* et la valeur à convertir vient ensuite ;

6. modificateur de longueur (facultatif) ;

7. type de conversion.

Lorsque l'argument de droite est un dictionnaire (ou un autre type de
*mapping*), les marqueurs dans le *bytes* *doivent* inclure une clé
présente dans le dictionnaire, écrite entre parenthèses,
immédiatement après le caractère "'%'". La clé indique quelle valeur
du dictionnaire doit être formatée. Par exemple :

>>> print(b'%(language)s has %(number)03d quote types.' %
...       {b'language': b"Python", b"number": 2})
b'Python has 002 quote types.'

Dans ce cas, aucune "*" ne peut se trouver dans le format (car ces "*"
nécessitent une liste (accès séquentiel) de paramètres).

Les caractères indicateurs de conversion sont :

+-----------+-----------------------------------------------------------------------+
| Option    | Signification                                                         |
|===========|=======================================================================|
| "'#'"     | La conversion utilise la « forme alternative » (définie ci-dessous).  |
+-----------+-----------------------------------------------------------------------+
| "'0'"     | Les valeurs numériques converties sont complétées de zéros.           |
+-----------+-----------------------------------------------------------------------+
| "'-'"     | La valeur convertie est ajustée à gauche (remplace la conversion      |
|           | "'0'" si les deux sont données).                                      |
+-----------+-----------------------------------------------------------------------+
| "' '"     | (une espace) Une espace doit être laissée avant un nombre positif (ou |
|           | chaîne vide) produite par la conversion d'une valeur signée.          |
+-----------+-----------------------------------------------------------------------+
| "'+'"     | Un caractère de signe ("'+'" ou "'-'") précède la valeur convertie    |
|           | (remplace le marqueur « espace »).                                    |
+-----------+-----------------------------------------------------------------------+

Un modificateur de longueur ("h", "l" ou "L") peut être présent, mais
est ignoré car il est pas nécessaire pour Python, donc par exemple
"%ld" est identique à "%d".

Les types utilisables dans les conversions sont :

+--------------+-------------------------------------------------------+---------+
| Conversion   | Signification                                         | Notes   |
|==============|=======================================================|=========|
| "'d'"        | Entier décimal signé.                                 |         |
+--------------+-------------------------------------------------------+---------+
| "'i'"        | Entier décimal signé.                                 |         |
+--------------+-------------------------------------------------------+---------+
| "'o'"        | Valeur octale signée.                                 | (1)     |
+--------------+-------------------------------------------------------+---------+
| "'u'"        | Type obsolète — identique à "'d'".                    | (8)     |
+--------------+-------------------------------------------------------+---------+
| "'x'"        | Hexadécimal signé (en minuscules).                    | (2)     |
+--------------+-------------------------------------------------------+---------+
| "'X'"        | Hexadécimal signé (capitales).                        | (2)     |
+--------------+-------------------------------------------------------+---------+
| "'e'"        | Floating-point exponential format (lowercase).        | (3)     |
+--------------+-------------------------------------------------------+---------+
| "'E'"        | Floating-point exponential format (uppercase).        | (3)     |
+--------------+-------------------------------------------------------+---------+
| "'f'"        | Floating-point decimal format.                        | (3)     |
+--------------+-------------------------------------------------------+---------+
| "'F'"        | Floating-point decimal format.                        | (3)     |
+--------------+-------------------------------------------------------+---------+
| "'g'"        | Floating-point format. Uses lowercase exponential     | (4)     |
|              | format if exponent is less than -4 or not less than   |         |
|              | precision, decimal format otherwise.                  |         |
+--------------+-------------------------------------------------------+---------+
| "'G'"        | Floating-point format. Uses uppercase exponential     | (4)     |
|              | format if exponent is less than -4 or not less than   |         |
|              | precision, decimal format otherwise.                  |         |
+--------------+-------------------------------------------------------+---------+
| "'c'"        | Octet simple (Accepte un nombre entier ou un seul     |         |
|              | objet *byte*).                                        |         |
+--------------+-------------------------------------------------------+---------+
| "'b'"        | Bytes (any object that follows the buffer protocol or | (5)     |
|              | has "__bytes__()").                                   |         |
+--------------+-------------------------------------------------------+---------+
| "'s'"        | "'s'" est un alias de "'b'" et ne devrait être        | (6)     |
|              | utilisé que pour du code Python2/3.                   |         |
+--------------+-------------------------------------------------------+---------+
| "'a'"        | *Bytes* (convertit n'importe quel objet Python en     | (5)     |
|              | utilisant "repr(obj).encode('ascii',                  |         |
|              | 'backslashreplace)").                                 |         |
+--------------+-------------------------------------------------------+---------+
| "'r'"        | "'r'" est un alias de "'a'" et ne devrait être        | (7)     |
|              | utilise que dans du code Python2/3.                   |         |
+--------------+-------------------------------------------------------+---------+
| "'%'"        | Aucun argument n'est converti, donne un caractère de  |         |
|              | "'%'" dans le résultat.                               |         |
+--------------+-------------------------------------------------------+---------+

Notes :

1. La forme alternative entraîne l'insertion d'un préfixe octal
   ("'0o'") avant le premier chiffre.

2. La forme alternative entraîne l'insertion d'un préfixe "'0x'" ou
   "'0X'" (respectivement pour les formats "'x'" et "'X'") avant le
   premier chiffre.

3. La forme alternative implique la présence d'un point décimal, même
   si aucun chiffre ne le suit.

   La précision détermine le nombre de chiffres après la virgule, 6
   par défaut.

4. La forme alternative implique la présence d'un point décimal et les
   zéros non significatifs sont conservés (ils ne le seraient pas
   autrement).

   La précision détermine le nombre de chiffres significatifs avant et
   après la virgule. 6 par défaut.

5. Si la précision est "N", la sortie est tronquée à "N" caractères.

6. "b'%s'" est obsolète, mais ne sera pas retiré des version 3.x.

7. "b'%r'" est obsolète mais ne sera pas retiré dans Python 3.x.

8. Voir la **PEP 237**.

Note:

  la version *bytearray* de cette méthode *ne modifie pas* les octets,
  elle produit toujours un nouvel objet, même si aucune modification
  n'a été effectuée.

Voir aussi:

  **PEP 461** -- Ajout du formatage via % aux *bytes* et *bytesarray*

Ajouté dans la version 3.5.


Vues mémoire
------------

Les "vues mémoire" permettent à du code Python d'accéder sans copie
aux données internes d'un objet prenant en charge le protocole tampon.

class memoryview(object)

      Crée une "vue mémoire" faisant référence à *object*. *object*
      doit savoir gérer le protocole tampon. "bytes" et "bytearray"
      sont des classes natives prenant en charge le protocole tampon.

      Une "vue mémoire" a la notion d'*élement*, qui est l'unité de
      mémoire atomique gérée par l'objet *object* d'origine. Pour de
      nombreux types simples comme "bytes" et "bytearray", l'élément
      est l'octet, mais pour d'autres types tels que "array.array" les
      éléments peuvent être plus grands.

      "len(view)" is equal to the length of "tolist", which is the
      nested list representation of the view. If "view.ndim = 1", this
      is equal to the number of elements in the view.

      Modifié dans la version 3.12: If "view.ndim == 0", "len(view)"
      now raises "TypeError" instead of returning 1.

      The "itemsize" attribute will give you the number of bytes in a
      single element.

      Une "vue mémoire" autorise le découpage et l'indiçage de ses
      données. Découper sur une dimension donne une sous-vue :

         >>> v = memoryview(b'abcefg')
         >>> v[1]
         98
         >>> v[-1]
         103
         >>> v[1:4]
         <memory at 0x7f3ddc9f4350>
         >>> bytes(v[1:4])
         b'bce'

      Si le "format" est un des formats natif du module "struct",
      indexer avec un nombre entier ou un *n*-uplet de nombres entiers
      est aussi autorisé et renvoie un seul *element* du bon type.
      Les vues mémoire unidimensionnelles peuvent être indexées avec
      un nombre entier ou un *n*-uplet d'un entier.  Les *memoryview*
      multi-dimensionnelles peuvent être indexées avec des
      *ndim*-uplets où *ndim* est le nombre de dimensions.  Les
      *memoryviews* à zéro dimension peuvent être indexées avec un
      *n*-uplet vide.

      Voici un exemple avec un autre format que *byte* :

         >>> import array
         >>> a = array.array('l', [-11111111, 22222222, -33333333, 44444444])
         >>> m = memoryview(a)
         >>> m[0]
         -11111111
         >>> m[-1]
         44444444
         >>> m[::2].tolist()
         [-11111111, -33333333]

      Si l'objet sous-jacent est accessible en écriture, la vue
      mémoire prend en charge les assignations de tranches
      unidimensionnelles. Redimensionner n'est cependant pas autorisé
      :

         >>> data = bytearray(b'abcefg')
         >>> v = memoryview(data)
         >>> v.readonly
         False
         >>> v[0] = ord(b'z')
         >>> data
         bytearray(b'zbcefg')
         >>> v[1:4] = b'123'
         >>> data
         bytearray(b'z123fg')
         >>> v[2:3] = b'spam'
         Traceback (most recent call last):
           File "<stdin>", line 1, in <module>
         ValueError: memoryview assignment: lvalue and rvalue have different structures
         >>> v[2:6] = b'spam'
         >>> data
         bytearray(b'z1spam')

      Les vues mémoire unidimensionnelles de *hachables* (lecture
      seule) avec les formats 'B', 'b', ou 'c' sont aussi hachables.
      La fonction de hachage est définie telle que "hash(m) ==
      hash(m.tobytes())" :

         >>> v = memoryview(b'abcefg')
         >>> hash(v) == hash(b'abcefg')
         True
         >>> hash(v[2:4]) == hash(b'ce')
         True
         >>> hash(v[::-2]) == hash(b'abcefg'[::-2])
         True

      Modifié dans la version 3.3: Les vues mémoire unidimensionnelles
      peuvent aussi être découpées. Les vues mémoire
      unidimensionnelles avec les formats 'B', 'b' ou 'c' sont
      maintenant *hachables*.

      Modifié dans la version 3.4: *memoryview* est maintenant
      enregistrée automatiquement avec "collections.abc.Sequence"

      Modifié dans la version 3.5: les vues mémoire peuvent maintenant
      être indicées par un *n*-uplet d'entiers.

      Modifié dans la version 3.14: memoryview is now a *generic
      type*.

      La classe "vue mémoire" dispose de plusieurs méthodes :

      __eq__(exporter)

         Une vue mémoire et un *exporter* de la **PEP 3118** sont
         égaux si leurs formes sont équivalentes et si toutes les
         valeurs correspondantes sont égales, les formats respectifs
         des opérandes étant interprétés en utilisant la syntaxe de
         "struct".

         Pour le sous-ensemble des formats de "struct" pris en charge
         par "tolist()", "v" et "w" sont égaux si "v.tolist()
         ==w.tolist()" :

            >>> import array
            >>> a = array.array('I', [1, 2, 3, 4, 5])
            >>> b = array.array('d', [1.0, 2.0, 3.0, 4.0, 5.0])
            >>> c = array.array('b', [5, 3, 1])
            >>> x = memoryview(a)
            >>> y = memoryview(b)
            >>> x == a == y == b
            True
            >>> x.tolist() == a.tolist() == y.tolist() == b.tolist()
            True
            >>> z = y[::-2]
            >>> z == c
            True
            >>> z.tolist() == c.tolist()
            True

         Si l'un des formats n'est pas géré par le module de "struct",
         les objets sont toujours considérés différents  (même si les
         formats et les valeurs contenues sont identiques) :

            >>> from ctypes import BigEndianStructure, c_long
            >>> class BEPoint(BigEndianStructure):
            ...     _fields_ = [("x", c_long), ("y", c_long)]
            ...
            >>> point = BEPoint(100, 200)
            >>> a = memoryview(point)
            >>> b = memoryview(point)
            >>> a == point
            False
            >>> a == b
            False

         Note that, as with floating-point numbers, "v is w" does
         *not* imply "v == w" for memoryview objects.

         Modifié dans la version 3.3: les versions précédentes
         comparaient la mémoire brute sans tenir compte du format de
         l'objet ni de sa structure logique.

      tobytes(order='C')

         Renvoie les données de la vue mémoire sous forme de *bytes*.
         Cela  équivaut à appeler le constructeur "bytes" sur la vue
         mémoire.

            >>> m = memoryview(b"abc")
            >>> m.tobytes()
            b'abc'
            >>> bytes(m)
            b'abc'

         Pour les tableaux non contigus le résultat est égal à la
         représentation en liste aplatie dont tous les éléments sont
         convertis en octets. "tobytes()" prend en charge toutes les
         chaînes de format, y compris celles qui ne sont pas connues
         du module "struct".

         Ajouté dans la version 3.8: *order* peut être "'C'", "'F'" ou
         "'A'". Lorsque *order* est "'C'" ou "'F'", les données du
         tableau original sont converties en ordre C ou Fortran. Pour
         les vues contiguës, "'A'" renvoie une copie exacte de la
         mémoire physique. En particulier, l'ordre Fortran en mémoire
         est conservé. Pour les vues non contiguës, les données sont
         d'abord converties en C. "order=None" est identique à
         "order='C'".

      hex(*, bytes_per_sep=1)
      hex(sep, bytes_per_sep=1)

         Renvoie une chaîne contenant deux chiffres hexadécimaux pour
         chaque octet de la mémoire.

            >>> m = memoryview(b"abc")
            >>> m.hex()
            '616263'

         Ajouté dans la version 3.5.

         Modifié dans la version 3.8: similaire à "bytes.hex()",
         "memoryview.hex()" prend désormais en charge les paramètres
         optionnels *sep* et *bytes_per_sep* pour insérer des
         séparateurs entre les octets dans la sortie hexadécimale.

      tolist()

         Renvoie les données de la mémoire sous la forme d'une liste
         d'éléments.

            >>> memoryview(b'abc').tolist()
            [97, 98, 99]
            >>> import array
            >>> a = array.array('d', [1.1, 2.2, 3.3])
            >>> m = memoryview(a)
            >>> m.tolist()
            [1.1, 2.2, 3.3]

         Modifié dans la version 3.3: "tolist()" prend désormais en
         charge tous les formats d'un caractère du module "struct"
         ainsi que des représentations multidimensionnelles.

      toreadonly()

         Renvoie une version en lecture seule de l'objet *memoryview*.
         L'objet original *memoryview* est inchangé.

            >>> m = memoryview(bytearray(b'abc'))
            >>> mm = m.toreadonly()
            >>> mm.tolist()
            [97, 98, 99]
            >>> mm[0] = 42
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            TypeError: cannot modify read-only memory
            >>> m[0] = 43
            >>> mm.tolist()
            [43, 98, 99]

         Ajouté dans la version 3.8.

      release()

         Libère le tampon sous-jacent exposé par l'objet *memoryview*.
         Beaucoup d'objets ont des comportements spécifiques
         lorsqu'ils sont liés à une vue (par exemple, un "bytearray"
         refusera temporairement de se faire redimensionner). Par
         conséquent, appeler *release()* peut être pratique pour lever
         ces restrictions (et libérer des ressources liées) aussi tôt
         que possible.

         Après le premier appel de cette méthode, toute nouvelle
         opération sur la vue mémoire lève une "ValueError" (sauf
         "release()" elle-même qui peut être appelée plusieurs fois) :

            >>> m = memoryview(b'abc')
            >>> m.release()
            >>> m[0]
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            ValueError: operation forbidden on released memoryview object

         Le protocole de gestion de contexte peut être utilisé pour
         obtenir un effet similaire, via l'instruction "with" :

            >>> with memoryview(b'abc') as m:
            ...     m[0]
            ...
            97
            >>> m[0]
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            ValueError: operation forbidden on released memoryview object

         Ajouté dans la version 3.2.

      cast(format, /)
      cast(format, shape, /)

         Change le format ou la forme d'une vue mémoire. Par défaut
         *shape* vaut "[byte_length//new_itemsize]", ce qui signifie
         que la vue résultante n'a qu'une dimension. La valeur
         renvoyée est une nouvelle vue mémoire, mais le tampon sous-
         jacent lui-même n'est pas copié. Les changements de format
         pris en charge sont « une dimension vers C-*contiguous* » et
         « *C-contiguous* vers une dimension ».

         The destination format is restricted to a single element
         native format in "struct" syntax. One of the formats must be
         a byte format ('B', 'b' or 'c'). The byte length of the
         result must be the same as the original length. Note that all
         byte lengths may depend on the operating system.

         Transformer un *1D/long* en *1D/unsigned bytes* :

            >>> import array
            >>> a = array.array('l', [1,2,3])
            >>> x = memoryview(a)
            >>> x.format
            'l'
            >>> x.itemsize
            8
            >>> len(x)
            3
            >>> x.nbytes
            24
            >>> y = x.cast('B')
            >>> y.format
            'B'
            >>> y.itemsize
            1
            >>> len(y)
            24
            >>> y.nbytes
            24

         Transformer un *1D/unsigned bytes* en *1D/char* :

            >>> b = bytearray(b'zyz')
            >>> x = memoryview(b)
            >>> x[0] = b'a'
            Traceback (most recent call last):
              ...
            TypeError: memoryview: invalid type for format 'B'
            >>> y = x.cast('c')
            >>> y[0] = b'a'
            >>> b
            bytearray(b'ayz')

         Transformer un *1D/bytes* en *3D/ints* en *1D/signed char* :

            >>> import struct
            >>> buf = struct.pack("i"*12, *list(range(12)))
            >>> x = memoryview(buf)
            >>> y = x.cast('i', shape=[2,2,3])
            >>> y.tolist()
            [[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]]
            >>> y.format
            'i'
            >>> y.itemsize
            4
            >>> len(y)
            2
            >>> y.nbytes
            48
            >>> z = y.cast('b')
            >>> z.format
            'b'
            >>> z.itemsize
            1
            >>> len(z)
            48
            >>> z.nbytes
            48

         Transformer un *1D/unsigned char* en *2D/unsigned long* :

            >>> buf = struct.pack("L"*6, *list(range(6)))
            >>> x = memoryview(buf)
            >>> y = x.cast('L', shape=[2,3])
            >>> len(y)
            2
            >>> y.nbytes
            48
            >>> y.tolist()
            [[0, 1, 2], [3, 4, 5]]

         Ajouté dans la version 3.3.

         Modifié dans la version 3.5: le format de la source n'est
         plus restreint lors de la transformation vers une vue
         d'octets.

      count(value, /)

         Count the number of occurrences of *value*.

         Ajouté dans la version 3.14.

   index(value, start=0, stop=sys.maxsize, /)

         Return the index of the first occurrence of *value* (at or
         after index *start* and before index *stop*).

         Raises a "ValueError" if *value* cannot be found.

         Ajouté dans la version 3.14.

      Plusieurs attributs en lecture seule sont également disponibles
      :

      obj

         L'objet sous-jacent de la vue mémoire :

            >>> b  = bytearray(b'xyz')
            >>> m = memoryview(b)
            >>> m.obj is b
            True

         Ajouté dans la version 3.3.

      nbytes

         "nbytes == product(shape) * itemsize == len(m.tobytes())".
         C'est l'espace que la liste occuperait en octets, dans une
         représentation contiguë. Ce n'est pas nécessairement égal à
         "len(m)" :

            >>> import array
            >>> a = array.array('i', [1,2,3,4,5])
            >>> m = memoryview(a)
            >>> len(m)
            5
            >>> m.nbytes
            20
            >>> y = m[::2]
            >>> len(y)
            3
            >>> y.nbytes
            12
            >>> len(y.tobytes())
            12

         Tableaux multidimensionnels :

            >>> import struct
            >>> buf = struct.pack("d"*12, *[1.5*x for x in range(12)])
            >>> x = memoryview(buf)
            >>> y = x.cast('d', shape=[3,4])
            >>> y.tolist()
            [[0.0, 1.5, 3.0, 4.5], [6.0, 7.5, 9.0, 10.5], [12.0, 13.5, 15.0, 16.5]]
            >>> len(y)
            3
            >>> y.nbytes
            96

         Ajouté dans la version 3.3.

      readonly

         Booléen indiquant si la mémoire est en lecture seule.

      format

         Chaîne contenant le format (dans le style de "struct") pour
         chaque élément de la vue. Une vue mémoire peut être créée
         depuis des exportateurs de formats arbitraires, mais
         certaines méthodes (comme "tolist()") sont limitées aux
         formats natifs à un seul élément.

         Modifié dans la version 3.3: le format "'B'" est maintenant
         traité selon la syntaxe du module *struct*. Cela signifie que
         "memoryview(b'abc')[0] == b'abc'[0] == 97".

      itemsize

         Taille en octets de chaque élément de la vue mémoire :

            >>> import array, struct
            >>> m = memoryview(array.array('H', [32000, 32001, 32002]))
            >>> m.itemsize
            2
            >>> m[0]
            32000
            >>> struct.calcsize('H') == m.itemsize
            True

      ndim

         Nombre de dimensions du tableau multi-dimensionnel pointé par
         la vue mémoire.

      shape

         "ndim"-uplet d'entiers donnant la forme du tableau à N
         dimensions pointé par la vue mémoire.

         Modifié dans la version 3.3: le *n*-uplet est vide au lieu de
         "None" lorsque *ndim* = 0.

      strides

         "ndim"-uplet d'entiers donnant la taille en octets permettant
         d'accéder à chaque élément pour chaque dimension du tableau.

         Modifié dans la version 3.3: le *n*-uplet est vide au lieu de
         "None" lorsque *ndim* = 0.

      suboffsets

         Détail de l'implémentation des *PIL-style arrays*. La valeur
         n'est donnée qu'à titre d'information.

      c_contiguous

         Booléen indiquant si la mémoire est C-*contiguë*.

         Ajouté dans la version 3.3.

      f_contiguous

         Booléen indiquant si la mémoire est Fortran-*contiguë*.

         Ajouté dans la version 3.3.

      contiguous

         Booléen indiquant si la mémoire est *contiguë*.

         Ajouté dans la version 3.3.


Types d'ensembles — "set", "frozenset"
======================================

Un ensemble (objet *set*) est une collection non triée d'objets
*hachables* distincts. Les utilisations classiques sont le test
d'appartenance, la déduplication d'une séquence, ou le calcul
d'opérations mathématiques telles que l'intersection, l'union, la
différence, ou la différence symétrique. (Pour les autres conteneurs,
voir les classes natives "dict", "liste", et "n-uplet", ainsi que le
module "collections".)

Comme pour les autres collections, les ensembles gèrent "x in set",
"len(set)", et "for x in set". En tant que collection non triée, les
ensembles n'enregistrent pas la position des éléments ou leur ordre
d'insertion. En conséquence, les ensembles n'autorisent ni
l'indexation, ni le découpage, ou tout autre comportement de séquence.

There are currently two built-in set types, "set" and "frozenset". The
"set" type is mutable --- the contents can be changed using methods
like "add()" and "remove()". Since it is mutable, it has no hash value
and cannot be used as either a dictionary key or as an element of
another set. The "frozenset" type is immutable and *hashable* --- its
contents cannot be altered after it is created; it can therefore be
used as a dictionary key or as an element of another set.

Des *sets* (mais pas des *frozensets*) peuvent être créés par une
liste d'éléments séparés par des virgules et entre accolades, par
exemple "{'jack', 'sjoerd'}", en plus du constructeur de la classe
"set".

Les constructeurs des deux classes fonctionnent de la même manière :

class set(iterable=(), /)
class frozenset(iterable=(), /)

   Renvoie un nouvel ensemble (*set* ou *frozenset*) dont les éléments
   viennent d'*iterable*.  Les éléments d'un *set* doivent être
   *hachables*.  Pour représenter des ensembles d'ensembles, les
   ensembles intérieurs doivent être des "frozenset".  Si *iterable*
   n'est pas spécifié, un nouvel ensemble vide est renvoyé.

Les ensembles peuvent être construits de différentes manières :

* en utilisant une liste d'éléments séparés par des virgules entre
  accolades : "{'jack', 'sjoerd'}" ;

* en utilisant un ensemble en compréhension : "{c for c in
  'abracadabra' if c not in 'abc'}" ;

* en utilisant le constructeur du type : "set()", "set('foobar')",
  "set(['a', 'b', 'foo'])".

Les instances de "set" et "frozenset" fournissent les opérations
suivantes :

len(s)

   Renvoie le nombre d'éléments dans l'ensemble *s* (cardinalité de
   *s*).

x in s

   Test d'appartenance de *x* dans *s*.

x not in s

   Test de non-appartenance de *x* dans *s*.

frozenset.isdisjoint(other, /)
set.isdisjoint(other, /)

   Renvoie "True" si l'ensemble n'a aucun élément en commun avec
   *other*.  Les ensembles sont disjoints si et seulement si leur
   intersection est un ensemble vide.

frozenset.issubset(other, /)
set.issubset(other, /)

set <= other

   Teste si tous les éléments de l'ensemble sont dans *other*.

set < other

   Teste si l'ensemble est un sous-ensemble propre de *other*,
   c'est-à-dire "set <= other and set != other".

frozenset.issuperset(other, /)
set.issuperset(other, /)

set >= other

   Teste si tous les éléments de *other* sont dans l'ensemble.

set > other

   Teste si l'ensemble est un sur-ensemble propre de *other*,
   c'est-à-dire, "set >= other and set != other".

frozenset.union(*others)
set.union(*others)

set | other | ...

   Renvoie un nouvel ensemble dont les éléments viennent de l'ensemble
   et de tous les autres (*others*).

frozenset.intersection(*others)
set.intersection(*others)

set & other & ...

   Renvoie un nouvel ensemble dont les éléments sont communs à
   l'ensemble et à tous les autres (*others*).

frozenset.difference(*others)
set.difference(*others)

set - other - ...

   Renvoie un nouvel ensemble dont les éléments sont dans l'ensemble
   mais ne sont dans aucun des autres.

frozenset.symmetric_difference(other, /)
set.symmetric_difference(other, /)

set ^ other

   Renvoie un nouvel ensemble dont les éléments sont soit dans
   l'ensemble, soit dans *other*, mais pas dans les deux.

frozenset.copy()
set.copy()

   Renvoie une copie superficielle du dictionnaire.

Note, the non-operator versions of "union()", "intersection()",
"difference()", "symmetric_difference()", "issubset()", and
"issuperset()" methods will accept any iterable as an argument.  In
contrast, their operator based counterparts require their arguments to
be sets.  This precludes error-prone constructions like "set('abc') &
'cbs'" in favor of the more readable "set('abc').intersection('cbs')".

Les classes "set" et "frozenset" gèrent les comparaisons d'ensemble à
ensemble. Deux ensembles sont égaux si et seulement si chaque élément
de chaque ensemble est contenu dans l'autre (autrement dit que chaque
ensemble est un sous-ensemble de l'autre). Un ensemble est plus petit
qu'un autre ensemble si et seulement si le premier est un sous-
ensemble propre du second (un sous-ensemble, mais pas égal). Un
ensemble est plus grand qu'un autre ensemble si et seulement si le
premier est un sur-ensemble propre du second (est un sur-ensemble mais
n'est pas égal).

Les instances de "set" se comparent aux instances de "frozenset" en
fonction de leurs membres.  Par exemple, "set('abc') ==
frozenset('abc')" envoie "True", ainsi que "set('abc') in
set([frozenset('abc')])".

Les tests de sous-ensemble et d'égalité ne se généralisent pas pour
former une fonction donnant un ordre total. Par exemple, deux
ensembles disjoints non vides ne sont ni égaux et ni des sous-
ensembles l'un de l'autre, donc toutes ces comparaisons donnent
"False" : "a<b", "a==b" et "a>b".

Puisque les ensembles ne définissent qu'un ordre partiel (par leurs
relations de sous-ensembles), la sortie de la méthode "list.sort()"
n'est pas définie pour des listes d'ensembles.

Les éléments des ensembles, comme les clés de dictionnaires, doivent
être *hachables*.

Les opérations binaires mélangeant des instances de "set" et
"frozenset" renvoient le type de la première opérande. Par exemple,
"frozenset('ab') | set('bc')" renvoie une instance de "frozenset".

La table suivante liste les opérations disponibles pour les "set" mais
qui ne s'appliquent pas aux instances de "frozenset" :

set.update(*others)

set |= other | ...

   Met à jour l'ensemble, ajoutant les éléments de tous les autres
   (*others*).

set.intersection_update(*others)

set &= other & ...

   Met à jour l'ensemble, ne gardant que les éléments trouvés dans
   tous les autres.

set.difference_update(*others)

set -= other | ...

   Met à jour l'ensemble, retirant les éléments trouvés dans les
   autres.

set.symmetric_difference_update(other, /)

set ^= other

   Met à jour l'ensemble, ne gardant que les éléments trouvés dans un
   des deux ensembles mais pas dans les deux.

set.add(elem, /)

   Ajoute l'élément *elem* à l'ensemble.

set.remove(elem, /)

   Retire l'élément *elem* de l'ensemble. Lève une exception
   "KeyError" si *elem* n'est pas dans l'ensemble.

set.discard(elem, /)

   Retire l'élément *elem* de l'ensemble s'il y est.

set.pop()

   Retire et renvoie un élément arbitraire de l'ensemble. Lève une
   exception "KeyError" si l'ensemble est vide.

set.clear()

   Supprime tous les éléments de l'ensemble.

Note, the non-operator versions of the "update()",
"intersection_update()", "difference_update()", and
"symmetric_difference_update()" methods will accept any iterable as an
argument.

Note, the *elem* argument to the "__contains__()", "remove()", and
"discard()" methods may be a set.  To support searching for an
equivalent frozenset, a temporary one is created from *elem*.


Les types de correspondances — "dict"
=====================================

Un objet *tableau de correspondances* (*mapping*) fait correspondre
des valeurs *hachables* à des objets arbitraires. Les tableaux de
correspondances sont des objets mutables. Il n'existe pour le moment
qu'un type de tableau de correspondances standard, le *dictionary*.
(Pour les autres conteneurs, voir les types natifs "liste", "ensemble"
et "n-uplet", ainsi que le module "collections".)

Les clés d'un dictionnaire sont *presque* des données arbitraires. Les
valeurs qui ne sont pas *hachables*, c'est-à-dire les valeurs
contenant des listes, dictionnaires ou autres types mutables (qui sont
comparés à l'aide de leurs valeurs plutôt que par l'identité de
l'objet) ne peuvent pas être utilisées comme clés. Des valeurs qui
sont considérées égales lors d'une comparaison (comme "1", "1.0" et
"True") peuvent être utilisées pour obtenir la même entrée d'un
dictionnaire.

class dict(**kwargs)
class dict(mapping, /, **kwargs)
class dict(iterable, /, **kwargs)

   Renvoie un nouveau dictionnaire initialisé à partir d'un argument
   positionnel optionnel, et un ensemble (vide ou non) d'arguments
   nommés.

   Les dictionnaires peuvent être construits de différentes manières :

   * en utilisant une liste de paires "clé: valeur" séparées par des
     virgules entre accolades : "{'jack': 4098, 'sjoerd': 4127}" ou
     "{4098: 'jack', 4127: 'sjoerd'}" ;

   * en utilisant un dictionnaire en compréhension : "{}", "{x: x ** 2
     for x in range(10)}" ;

   * en utilisant le constructeur du type : "dict()", "dict([('foo',
     100), ('bar', 200)])", "dict(foo=100, bar=200)".

   If no positional argument is given, an empty dictionary is created.
   If a positional argument is given and it defines a "keys()" method,
   a dictionary is created by calling "__getitem__()" on the argument
   with each returned key from the method.  Otherwise, the positional
   argument must be an *iterable* object.  Each item in the iterable
   must itself be an iterable with exactly two elements.  The first
   element of each item becomes a key in the new dictionary, and the
   second element the corresponding value.  If a key occurs more than
   once, the last value for that key becomes the corresponding value
   in the new dictionary.

   Si des arguments nommés sont donnés, ils sont ajoutés au
   dictionnaire créé depuis l'argument positionnel. Si une clé est
   déjà présente, la valeur de l'argument nommé remplace la valeur
   reçue par l'argument positionnel.

   Dictionaries compare equal if and only if they have the same "(key,
   value)" pairs (regardless of ordering). Order comparisons ('<',
   '<=', '>=', '>') raise "TypeError".  To illustrate dictionary
   creation and equality, the following examples all return a
   dictionary equal to "{"one": 1, "two": 2, "three": 3}":

      >>> a = dict(one=1, two=2, three=3)
      >>> b = {'one': 1, 'two': 2, 'three': 3}
      >>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
      >>> d = dict([('two', 2), ('one', 1), ('three', 3)])
      >>> e = dict({'three': 3, 'one': 1, 'two': 2})
      >>> f = dict({'one': 1, 'three': 3}, two=2)
      >>> a == b == c == d == e == f
      True

   Fournir les arguments nommés comme dans le premier exemple ne
   fonctionne que pour des clés qui sont des identifiants valides en
   Python. Dans les autres cas, toutes les clés valides sont
   utilisables.

   Les dictionnaires préservent l'ordre des insertions. Notez que
   modifier une clé n'affecte pas l'ordre. Les clés ajoutées après un
   effacement sont insérées à la fin.

      >>> d = {"one": 1, "two": 2, "three": 3, "four": 4}
      >>> d
      {'one': 1, 'two': 2, 'three': 3, 'four': 4}
      >>> list(d)
      ['one', 'two', 'three', 'four']
      >>> list(d.values())
      [1, 2, 3, 4]
      >>> d["one"] = 42
      >>> d
      {'one': 42, 'two': 2, 'three': 3, 'four': 4}
      >>> del d["two"]
      >>> d["two"] = None
      >>> d
      {'one': 42, 'three': 3, 'four': 4, 'two': None}

   Modifié dans la version 3.7: l'ordre d'un dictionnaire est toujours
   l'ordre des insertions. Ce comportement était un détail
   d'implémentation de CPython depuis la version 3.6.

   Voici les opérations gérées par les dictionnaires (par conséquent,
   d'autres types de tableaux de correspondances devraient les gérer
   aussi) :

   list(d)

      Renvoie une liste de toutes les clés utilisées dans le
      dictionnaire *d*.

   len(d)

      Renvoie le nombre d'éléments dans le dictionnaire *d*.

   d[key]

      Renvoie l'élément de *d* dont la clé est *key*. Lève une
      exception "KeyError" si *key* n'est pas dans le dictionnaire.

      If a subclass of dict defines a method "__missing__()" and *key*
      is not present, the "d[key]" operation calls that method with
      the key *key* as argument.  The "d[key]" operation then returns
      or raises whatever is returned or raised by the
      "__missing__(key)" call. No other operations or methods invoke
      "__missing__()". If "__missing__()" is not defined, "KeyError"
      is raised. "__missing__()" must be a method; it cannot be an
      instance variable:

         >>> class Counter(dict):
         ...     def __missing__(self, key):
         ...         return 0
         ...
         >>> c = Counter()
         >>> c['red']
         0
         >>> c['red'] += 1
         >>> c['red']
         1

      The example above shows part of the implementation of
      "collections.Counter". A different "__missing__()" method is
      used by "collections.defaultdict".

   d[key] = value

      Assigne "d[key]" à *value*.

   del d[key]

      Supprime "d[key]" de *d*.  Lève une exception "KeyError" si
      *key* n'est pas dans le dictionnaire.

   key in d

      Renvoie "True" si *d* a la clé *key*, sinon "False".

   key not in d

      Équivalent à "not key in d".

   iter(d)

      Renvoie un itérateur sur les clés du dictionnaire. C'est un
      raccourci pour "iter(d.keys())".

   clear()

      Supprime tous les éléments du dictionnaire.

   copy()

      Renvoie une copie superficielle du dictionnaire.

   classmethod fromkeys(iterable, value=None, /)

      Crée un nouveau dictionnaire avec les clés de *iterable* et les
      valeurs à *value*.

      "fromkeys()" est une méthode de classe qui renvoie un nouveau
      dictionnaire. *value* vaut par défaut "None". Toutes les valeurs
      se réfèrent à une seule instance, donc il n'est généralement pas
      logique que *value* soit un objet mutable comme une liste vide.
      Pour avoir des valeurs distinctes, utilisez plutôt une
      compréhension de dictionnaire.

   get(key, default=None, /)

      Renvoie la valeur de *key* si *key* est dans le dictionnaire,
      sinon *default*. Si *default* n'est pas donné, il vaut "None"
      par défaut, de manière à ce que cette méthode ne lève jamais
      "KeyError".

   items()

      Renvoie une nouvelle vue des éléments du dictionnaire (paires de
      "(key, value)"). Voir la documentation des vues.

   keys()

      Renvoie une nouvelle vue des clés du dictionnaire. Voir la
      documentation des vues.

   pop(key, /)
   pop(key, default, /)

      Si *key* est dans le dictionnaire elle est supprimée et sa
      valeur est renvoyée, sinon renvoie *default*.  Si *default*
      n'est pas donné et que *key* n'est pas dans le dictionnaire, une
      "KeyError" est levée.

   popitem()

      Supprime et renvoie une paire "(key, value)" du dictionnaire.
      Les paires sont renvoyées dans un ordre LIFO (Last In - First
      Out c.-à-d. dernier entré, premier sorti).

      "popitem()" est pratique pour itérer un dictionnaire de manière
      destructive, comme souvent dans les algorithmes sur les
      ensembles.  Si le dictionnaire est vide, appeler "popitem()"
      lève une "KeyError".

      Modifié dans la version 3.7: l'ordre « dernier entré, premier
      sorti » (LIFO) est désormais assuré. Dans les versions
      précédentes, "popitem()" renvoyait une paire clé-valeur
      arbitraire.

   reversed(d)

      Renvoie un itérateur inversé sur les clés du dictionnaire. C'est
      un raccourci pour "reversed(d.keys())".

      Ajouté dans la version 3.8.

   setdefault(key, default=None, /)

      Si *key* est dans le dictionnaire, sa valeur est renvoyée.
      Sinon, insère *key* avec comme valeur *default* et renvoie
      *default*. *default* vaut "None" par défaut.

   update(**kwargs)
   update(mapping, /, **kwargs)
   update(iterable, /, **kwargs)

      Update the dictionary with the key/value pairs from *mapping* or
      *iterable* and *kwargs*, overwriting existing keys.  Return
      "None".

      "update()" accepts either another object with a "keys()" method
      (in which case "__getitem__()" is called with every key returned
      from the method) or an iterable of key/value pairs (as tuples or
      other iterables of length two). If keyword arguments are
      specified, the dictionary is then updated with those key/value
      pairs: "d.update(red=1, blue=2)".

   values()

      Renvoie une nouvelle vue des valeurs du dictionnaire.  Voir la
      documentation des vues.

      Une comparaison d'égalité entre une vue de "dict.values()" et
      une autre renvoie toujours "False". Cela s'applique aussi
      lorsque l'on compare "dict.values()" à lui-même :

         >>> d = {'a': 1}
         >>> d.values() == d.values()
         False

   d | other

      Crée un nouveau dictionnaire avec les clés et les valeurs
      fusionnées de *d* et *other*, qui doivent tous deux être des
      dictionnaires. Les valeurs de *other* sont prioritaires lorsque
      *d* et *other* partagent des clés.

      Ajouté dans la version 3.9.

   d |= other

      Met à jour le dictionnaire *d* avec les clés et les valeurs de
      *other*, qui peut être soit un *tableau de correspondances* soit
      un *itérable* de paires clé-valeur. Les valeurs de *other* sont
      prioritaires lorsque *d* et *other* partagent des clés.

      Ajouté dans la version 3.9.

   Les dictionnaires et les vues de dictionnaires sont réversibles.

      >>> d = {"one": 1, "two": 2, "three": 3, "four": 4}
      >>> d
      {'one': 1, 'two': 2, 'three': 3, 'four': 4}
      >>> list(reversed(d))
      ['four', 'three', 'two', 'one']
      >>> list(reversed(d.values()))
      [4, 3, 2, 1]
      >>> list(reversed(d.items()))
      [('four', 4), ('three', 3), ('two', 2), ('one', 1)]

   Modifié dans la version 3.8: les dictionnaires sont maintenant
   réversibles.

Voir aussi:

  "types.MappingProxyType" peut être utilisé pour créer une vue en
  lecture seule d'un "dict".

-[ Thread safety for dict objects ]-

Creating a dictionary with the "dict" constructor is atomic when the
argument to it is a "dict" or a "tuple". When using the
"dict.fromkeys()" method, dictionary creation is atomic when the
argument is a "dict", "tuple", "set" or "frozenset".

The following operations and functions are *lock-free* and *atomic*.

   d[key]       # dict.__getitem__
   d.get(key)   # dict.get
   key in d     # dict.__contains__
   len(d)       # dict.__len__

All other operations from here on hold the *per-object lock*.

Writing or removing a single item is safe to call from multiple
threads and will not corrupt the dictionary:

   d[key] = value        # write
   del d[key]            # delete
   d.pop(key)            # remove and return
   d.popitem()           # remove and return last item
   d.setdefault(key, v)  # insert if missing

These operations may compare keys using "__eq__()", which can execute
arbitrary Python code. During such comparisons, the dictionary may be
modified by another thread. For built-in types like "str", "int", and
"float", that implement "__eq__()" in C, the underlying lock is not
released during comparisons and this is not a concern.

The following operations return new objects and hold the *per-object
lock* for the duration of the operation:

   d.copy()      # returns a shallow copy of the dictionary
   d | other     # merges two dicts into a new dict
   d.keys()      # returns a new dict_keys view object
   d.values()    # returns a new dict_values view object
   d.items()     # returns a new dict_items view object

The "clear()" method holds the lock for its duration. Other threads
cannot observe elements being removed.

The following operations lock both dictionaries. For "update()" and
"|=", this applies only when the other operand is a "dict" that uses
the standard dict iterator (but not subclasses that override
iteration). For equality comparison, this applies to "dict" and its
subclasses:

   d.update(other_dict)  # both locked when other_dict is a dict
   d |= other_dict       # both locked when other_dict is a dict
   d == other_dict       # both locked for dict and subclasses

All comparison operations also compare values using "__eq__()", so for
non-built-in types the lock may be released during comparison.

"fromkeys()" locks both the new dictionary and the iterable when the
iterable is exactly a "dict", "set", or "frozenset" (not subclasses):

   dict.fromkeys(a_dict)      # locks both
   dict.fromkeys(a_set)       # locks both
   dict.fromkeys(a_frozenset) # locks both

When updating from a non-dict iterable, only the target dictionary is
locked. The iterable may be concurrently modified by another thread:

   d.update(iterable)        # iterable is not a dict: only d locked
   d |= iterable             # iterable is not a dict: only d locked
   dict.fromkeys(iterable)   # iterable is not a dict/set/frozenset: only result locked

Operations that involve multiple accesses, as well as iteration, are
never atomic:

   # NOT atomic: read-modify-write
   d[key] = d[key] + 1

   # NOT atomic: check-then-act (TOCTOU)
   if key in d:
         del d[key]

   # NOT thread-safe: iteration while modifying
   for key, value in d.items():
         process(key)  # another thread may modify d

To avoid time-of-check to time-of-use (TOCTOU) issues, use atomic
operations or handle exceptions:

   # Use pop() with default instead of check-then-delete
   d.pop(key, None)

   # Or handle the exception
   try:
         del d[key]
   except KeyError:
         pass

To safely iterate over a dictionary that may be modified by another
thread, iterate over a copy:

   # Make a copy to iterate safely
   for key, value in d.copy().items():
         process(key)

Consider external synchronization when sharing "dict" instances across
threads. See Python support for free threading for more information.


Les vues de dictionnaires
-------------------------

Les objets renvoyés par "dict.keys()", "dict.values()" et
"dict.items()" sont des *vues*.  Ils fournissent une vue dynamique des
éléments du dictionnaire, ce qui signifie que si le dictionnaire
change, la vue reflète ces changements.

Les vues de dictionnaires peuvent être itérées et ainsi renvoyer les
données du dictionnaire ; elles gèrent aussi les tests d'appartenance
:

len(dictview)

   Renvoie le nombre d'entrées du dictionnaire.

iter(dictview)

   Renvoie un itérateur sur les clés, les valeurs ou les éléments
   (représentés par des paires "(clé, valeur)") du dictionnaire.

   Les clés et les valeurs sont itérées dans l'ordre de leur
   insertion. Ceci permet la création de paires de "(key, value)" en
   utilisant "zip()" : "pairs = zip(d.values(), d.keys())". Un autre
   moyen de construire la même liste est "pairs = [(v, k) for (k, v)
   in d.items()]".

   Parcourir des vues tout en ajoutant ou supprimant des entrées dans
   un dictionnaire peut lever une "RuntimeError" ou ne pas fournir
   toutes les entrées.

   Modifié dans la version 3.7: l'ordre d'un dictionnaire est toujours
   l'ordre des insertions.

x in dictview

   Renvoie "True" si *x* est dans les clés, les valeurs ou les
   éléments du dictionnaire sous-jacent (dans le dernier cas, *x* doit
   être une paire "(key, value)").

reversed(dictview)

   Renvoie un itérateur inversé sur les clés, les valeurs ou les
   éléments du dictionnaire. La vue est itérée dans l'ordre inverse
   d'insertion.

   Modifié dans la version 3.8: les vues de dictionnaires sont
   dorénavant réversibles.

dictview.mapping

   Renvoie une "types.MappingProxyType" qui encapsule le dictionnaire
   original auquel la vue se réfère.

   Ajouté dans la version 3.10.

Keys views are set-like since their entries are unique and *hashable*.
Items views also have set-like operations since the (key, value) pairs
are unique and the keys are hashable. If all values in an items view
are hashable as well, then the items view can interoperate with other
sets. (Values views are not treated as set-like since the entries are
generally not unique.)  For set-like views, all of the operations
defined for the abstract base class "collections.abc.Set" are
available (for example, "==", "<", or "^").  While using set
operators, set-like views accept any iterable as the other operand,
unlike sets which only accept sets as the input.

Voici un exemple d'utilisation de vue de dictionnaire :

   >>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
   >>> keys = dishes.keys()
   >>> values = dishes.values()

   >>> # iteration
   >>> n = 0
   >>> for val in values:
   ...     n += val
   ...
   >>> print(n)
   504

   >>> # keys and values are iterated over in the same order (insertion order)
   >>> list(keys)
   ['eggs', 'sausage', 'bacon', 'spam']
   >>> list(values)
   [2, 1, 1, 500]

   >>> # view objects are dynamic and reflect dict changes
   >>> del dishes['eggs']
   >>> del dishes['sausage']
   >>> list(keys)
   ['bacon', 'spam']

   >>> # set operations
   >>> keys & {'eggs', 'bacon', 'salad'}
   {'bacon'}
   >>> keys ^ {'sausage', 'juice'} == {'juice', 'sausage', 'bacon', 'spam'}
   True
   >>> keys | ['juice', 'juice', 'juice'] == {'bacon', 'spam', 'juice'}
   True

   >>> # get back a read-only proxy for the original dictionary
   >>> values.mapping
   mappingproxy({'bacon': 1, 'spam': 500})
   >>> values.mapping['spam']
   500


Le type gestionnaire de contexte
================================

L'instruction Python "with" permet de créer des contextes d'exécution
à l'aide de gestionnaires de contextes. L'implémentation est réalisée
via deux méthodes permettant aux classes définies par l'utilisateur de
définir un contexte d'exécution, dans lequel on entre avant
l'exécution du corps de l'instruction et que l'on quitte lorsque
l'instruction se termine :

contextmanager.__enter__()

   Entre dans le contexte d'exécution, soit se renvoyant lui-même,
   soit en renvoyant un autre objet en lien avec ce contexte. La
   valeur renvoyée par cette méthode est liée à l'identifiant donné au
   "as" de l'instruction "with" utilisant ce gestionnaire de contexte.

   Un exemple de gestionnaire de contexte se renvoyant lui-même est
   l'*objet fichier*. Les objets fichiers se renvoient eux-mêmes
   depuis "__enter__()" pour ainsi permettre à "open()" d'être
   utilisée comme expression dans une instruction "with".

   Un exemple de gestionnaire de contexte renvoyant un objet connexe
   est celui renvoyé par "decimal.localcontext()". Ces gestionnaires
   remplacent le contexte décimal courant par une copie de l'original,
   copie qui est renvoyée. Ça permet de changer le contexte courant
   dans le corps du "with" sans affecter le code en dehors de
   l'instruction "with".

contextmanager.__exit__(exc_type, exc_val, exc_tb)

   Sort du contexte et renvoie un booléen indiquant si une exception
   est survenue et doit être supprimée.  Si une exception est survenue
   lors de l'exécution du corps de l'instruction "with", les arguments
   contiennent le type de l'exception, sa valeur et la trace de la
   pile (*traceback*). Sinon les trois arguments valent "None".

   Returning a true value from this method will cause the "with"
   statement to suppress the exception and continue execution with the
   statement immediately following the "with" statement. Otherwise the
   exception continues propagating after this method has finished
   executing.

   If this method raises an exception while handling an earlier
   exception from the "with" block, the new exception is raised, and
   the original exception is stored in its "__context__" attribute.

   L'exception reçue ne doit jamais être relancée explicitement, cette
   méthode devrait plutôt renvoyer une valeur fausse pour indiquer que
   son exécution s'est terminée avec succès et qu'elle ne veut pas
   supprimer l'exception. Ceci permet au code de gestion du contexte
   de comprendre si une méthode "__exit__()" a échoué.

Python définit plusieurs gestionnaires de contexte pour faciliter la
synchronisation des fils d'exécution, la fermeture des fichiers ou
d'autres objets, et la configuration du contexte arithmétique décimal.
Ces types spécifiques ne sont pas traités différemment, ils respectent
simplement le protocole de gestion du contexte. Voir les exemples dans
la documentation du module "contextlib".

Les *générateurs* Python et le décorateur "contextlib.contextmanager"
permettent d'implémenter simplement ces protocoles. Si un générateur
est décoré avec "contextlib. contextmanager", il renvoie un
gestionnaire de contexte implémentant les méthodes "__enter__()" et
"__exit__()", plutôt que l'itérateur produit par un générateur non
décoré.

Notez qu'il n'y a pas d'emplacement spécifique pour ces méthodes dans
la structure de type pour les objets Python dans l'API Python/C. Les
types souhaitant définir ces méthodes doivent les fournir comme une
méthode accessible en Python. Comparé au coût de la mise en place du
contexte d'exécution, le coût d'un accès au dictionnaire d'une classe
unique est négligeable.


Types d'annotation de type — Alias générique, Union
===================================================

Les principaux types natifs pour l'*annotation de types* sont l'Alias
générique et l'Union.


Type Alias générique
--------------------

Les objets "GenericAlias" sont généralement créés en indiçant une
classe. Ils sont le plus souvent utilisés avec des classes conteneurs,
telles que "list" ou "dict". Par exemple, "list[int]" est un objet
GenericAlias créé en indiçant la classe "list" avec l'argument "int".
Les objets "GenericAlias" sont principalement destinés à être utilisés
en tant qu'*annotations de types*.

Note:

  il n'est généralement possible d'indicer une classe que si la classe
  implémente la méthode spéciale "__class_getitem__()".

Un objet "GenericAlias" agit comme un mandataire pour un *type
générique*, en implémentant des *types génériques pouvant recevoir des
paramètres*.

Pour une classe conteneur, les arguments fournis comme indices de la
classe indiquent les types des éléments que l'objet peut contenir. Par
exemple, "set[bytes]" peut être utilisé dans les annotations de type
pour signifier un "ensemble" dans lequel tous les éléments sont de
type "bytes".

Pour une classe qui définit "__class_getitem__()" mais n'est pas un
conteneur, les arguments fournis comme indices de la classe indiquent
souvent les types de retour d'une ou plusieurs méthodes définies sur
un objet. Par exemple, "re" (expressions rationnelles) peut être
utilisé à la fois sur le type de données "str" et sur le type de
données "bytes" :

* si "x = re.search('foo', 'foo')", "x" est un objet re.Match où les
  valeurs de retour de "x.group(0)" et "x[0]" sont toutes les deux de
  type "str". Nous pouvons représenter ce type d'objet dans des
  annotations de type avec le "GenericAlias" "re.Match[str]" ;

* si "y = re.search(b'bar', b'bar')", (notez le "b" pour "bytes"), "y"
  est également une instance de "re.Match", mais les valeurs de retour
  de "y.group(0)" et "y[0]" sont toutes les deux de type "bytes". Dans
  les annotations de type, nous représenterons cette variété d'objets
  re.Match par "re.Match[bytes]".

Les objets "GenericAlias" sont des instances de la classe
"types.GenericAlias", qui peut également être utilisée pour créer
directement des objets "GenericAlias".

T[X, Y, ...]

   Crée un "GenericAlias" représentant un type "T" paramétré par les
   types *X*, *Y* et plus selon le "T" utilisé. Par exemple, pour une
   fonction attendant une "list" contenant des éléments "float" :

      def average(values: list[float]) -> float:
          return sum(values) / len(values)

   Un autre exemple peut être un objet *tableau de correspondances*,
   utilisant un "dict", qui est un type générique attendant deux
   paramètres de type représentant le type clé et le type valeur. Dans
   cet exemple, la fonction attend un "dict" avec des clés de type
   "str" et des valeurs de type "int" :

      def send_post_request(url: str, body: dict[str, int]) -> None:
          ...

Les fonctions natives "isinstance()" et "issubclass()" n'acceptent pas
les types "GenericAlias" pour leur second argument :

   >>> isinstance([1, 2], list[str])
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: isinstance() argument 2 cannot be a parameterized generic

Lors de l'exécution, Python ne regarde pas les *annotations de type*.
Cela vaut pour les types génériques et les types qu'on leur passe en
paramètres. Lors de la création d'un objet conteneur à partir d'un
"GenericAlias", les types des éléments du conteneur ne sont pas
vérifiés. Par exemple, le code suivant est déconseillé, mais s'exécute
sans erreur :

   >>> t = list[str]
   >>> t([1, 2, 3])
   [1, 2, 3]

De plus, les types génériques pouvant recevoir des paramètres effacent
les paramètres de type lors de la création d'objet :

   >>> t = list[str]
   >>> type(t)
   <class 'types.GenericAlias'>

   >>> l = t()
   >>> type(l)
   <class 'list'>

Appeler "repr()" ou "str()" sur un type générique affiche le type
pouvant recevoir des paramètres :

   >>> repr(list[int])
   'list[int]'

   >>> str(list[int])
   'list[int]'

La méthode "__getitem__()" des conteneurs génériques lève une
exception pour interdire les erreurs telles que "dict[str][str]" :

   >>> dict[str][str]
   Traceback (most recent call last):
     ...
   TypeError: dict[str] is not a generic class

Cependant, de telles expressions sont valides lorsque des variables de
type sont utilisées. L'indice doit avoir autant d'éléments qu'il y a
d'éléments variables de type dans l'objet "GenericAlias" "__args__".

   >>> from typing import TypeVar
   >>> Y = TypeVar('Y')
   >>> dict[str, Y][int]
   dict[str, int]


Classes génériques standards
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Les classes suivantes de la bibliothèque standard prennent en charge
les types génériques pouvant accepter des paramètres. Cette liste est
non exhaustive.

* "tuple"

* "list"

* "dict"

* "set"

* "frozenset"

* "type"

* "asyncio.Future"

* "asyncio.Task"

* "collections.deque"

* "collections.defaultdict"

* "collections.OrderedDict"

* "collections.Counter"

* "collections.ChainMap"

* "collections.abc.Awaitable"

* "collections.abc.Coroutine"

* "collections.abc.AsyncIterable"

* "collections.abc.AsyncIterator"

* "collections.abc.AsyncGenerator"

* "collections.abc.Iterable"

* "collections.abc.Iterator"

* "collections.abc.Generator"

* "collections.abc.Reversible"

* "collections.abc.Container"

* "collections.abc.Collection"

* "collections.abc.Callable"

* "collections.abc.Set"

* "collections.abc.MutableSet"

* "collections.abc.Mapping"

* "collections.abc.MutableMapping"

* "collections.abc.Sequence"

* "collections.abc.MutableSequence"

* "collections.abc.ByteString"

* "collections.abc.MappingView"

* "collections.abc.KeysView"

* "collections.abc.ItemsView"

* "collections.abc.ValuesView"

* "contextlib.AbstractContextManager"

* "contextlib.AbstractAsyncContextManager"

* "dataclasses.Field"

* "functools.cached_property"

* "functools.partialmethod"

* "os.PathLike"

* "queue.LifoQueue"

* "queue.Queue"

* "queue.PriorityQueue"

* "queue.SimpleQueue"

* re.Pattern

* re.Match

* "shelve.BsdDbShelf"

* "shelve.DbfilenameShelf"

* "shelve.Shelf"

* "types.MappingProxyType"

* "weakref.WeakKeyDictionary"

* "weakref.WeakMethod"

* "weakref.WeakSet"

* "weakref.WeakValueDictionary"


Attributs spéciaux des alias génériques
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Tous les types génériques pouvant accepter des paramètres implémentent
des attributs spéciaux en lecture seule.

genericalias.__origin__

   Cet attribut pointe vers la classe générique sans paramètres :

      >>> list[int].__origin__
      <class 'list'>

genericalias.__args__

   Cet attribut est un "n-uplet" (éventuellement de longueur 1) de
   types génériques passés à la "__class_getitem__()" d'origine de la
   classe générique :

      >>> dict[str, list[int]].__args__
      (<class 'str'>, list[int])

genericalias.__parameters__

   Cet attribut est un *n*-uplet calculé paresseusement
   (éventuellement vide) de variables de type (chaque type n'est
   mentionné qu'une seule fois) trouvées dans "__args__" :

      >>> from typing import TypeVar

      >>> T = TypeVar('T')
      >>> list[T].__parameters__
      (~T,)

   Note:

     un objet "GenericAlias" avec des paramètres "typing.ParamSpec"
     peut ne pas avoir de "__parameters__" corrects après substitution
     car "typing.ParamSpec" est principalement destiné à la
     vérification de type statique.

genericalias.__unpacked__

   Booléen qui est vrai si l'alias a été décompressé à l'aide de
   l'opérateur "*" (voir "TypeVarTuple").

   Ajouté dans la version 3.11.

Voir aussi:

  **PEP 484** - Indications des types (page en anglais)
     Présentation du cadre Python pour les annotations de type.

  **PEP 585** – Types génériques d'indication de type dans les
  conteneurs standard (page en anglais)
     Présentation de la possibilité de paramétrer nativement les
     classes de la bibliothèque standard, à condition qu'elles
     implémentent la méthode de classe spéciale "__class_getitem__()".

  Génériques, génériques personnalisés et "typing.Generic"
     Documentation sur la façon d'implémenter des classes génériques
     qui peuvent être paramétrées à l'exécution et comprises par les
     vérificateurs de type statiques.

Ajouté dans la version 3.9.


Type Union
----------

A union object holds the value of the "|" (bitwise or) operation on
multiple type objects.  These types are intended primarily for *type
annotations*. The union type expression enables cleaner type hinting
syntax compared to subscripting "typing.Union".

X | Y | ...

   Définit un objet *union* qui contient les types *X*, *Y*, etc. "X |
   Y" signifie X ou Y. Cela équivaut à "typing.Union[X, Y]". Par
   exemple, la fonction suivante attend un argument de type "int" ou
   "float" :

      def square(number: int | float) -> int | float:
          return number ** 2

   Note:

     The "|" operand cannot be used at runtime to define unions where
     one or more members is a forward reference. For example, "int |
     "Foo"", where ""Foo"" is a reference to a class not yet defined,
     will fail at runtime. For unions which include forward
     references, present the whole expression as a string, e.g. ""int
     | Foo"".

union_object == other

   Les objets *union* peuvent être testés pour savoir s'ils sont égaux
   à d'autres objets *union*. Plus en détails :

   * Les unions d'unions sont aplaties :

        (int | str) | float == int | str | float

   * Les types redondants sont supprimés :

        int | str | int == int | str

   * Lors de la comparaison d'unions, l'ordre est ignoré :

        int | str == str | int

   * It creates instances of "typing.Union":

        int | str == typing.Union[int, str]
        type(int | str) is typing.Union

   * Les types optionnels peuvent être orthographiés comme une union
     avec "None" :

        str | None == typing.Optional[str]

isinstance(obj, union_object)

issubclass(obj, union_object)

   Les appels à "isinstance()" et "issubclass()" sont également pris
   en charge avec un objet *union* :

      >>> isinstance("", int | str)
      True

   However, parameterized generics in union objects cannot be checked:

      >>> isinstance(1, int | list[int])  # short-circuit evaluation
      True
      >>> isinstance([1], int | list[int])
      Traceback (most recent call last):
        ...
      TypeError: isinstance() argument 2 cannot be a parameterized generic

The user-exposed type for the union object can be accessed from
"typing.Union" and used for "isinstance()" checks:

   >>> import typing
   >>> isinstance(int | str, typing.Union)
   True
   >>> typing.Union()
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: cannot create 'typing.Union' instances

Note:

  The "__or__()" method for type objects was added to support the
  syntax "X | Y".  If a metaclass implements "__or__()", the Union may
  override it:

     >>> class M(type):
     ...     def __or__(self, other):
     ...         return "Hello"
     ...
     >>> class C(metaclass=M):
     ...     pass
     ...
     >>> C | int
     'Hello'
     >>> int | C
     int | C

Voir aussi:

  **PEP 604** – PEP proposant la syntaxe  "X | Y" et le type *Union*.

Ajouté dans la version 3.10.

Modifié dans la version 3.14: Union objects are now instances of
"typing.Union". Previously, they were instances of "types.UnionType",
which remains an alias for "typing.Union".


Autres types natifs
===================

L'interpréteur gère aussi d'autres types d'objets, la plupart ne
gèrent cependant qu'une ou deux opérations.


Modules
-------

La seule opération spéciale sur un module est l'accès à ses attributs
: "m.name", où *m* est un module et *name* donne accès un nom défini
dans la table des symboles de *m*.  Il est possible d'assigner un
attribut de module.  (Notez que l'instruction "import" n'est pas
strictement une opération sur un objet module. "import foo" ne
nécessite pas qu'un objet module nommé *foo* existe, il nécessite
cependant une *définition* (externe) d'un module nommé *foo* quelque
part.)

Un attribut spécial à chaque module est "__dict__". C'est le
dictionnaire contenant la table des symboles du module. Modifier ce
dictionnaire change la table des symboles du module, mais assigner
directement "__dict__" n'est pas possible (vous pouvez écrire
"m.__dict__['a'] = 1", qui donne "1" comme valeur pour "m.a", mais
vous ne pouvez pas écrire "m.__dict__ = {}"). Modifier "__dict__"
directement n'est pas recommandé.

Les modules natifs de l'interpréteur sont affichés comme "<module
'sys' (built-in)>".  S'ils sont chargés depuis un fichier, ils sont
affichés sous la forme "<module 'os' from
'/usr/local/lib/pythonX.Y/os.pyc'>".


Les classes et instances de classes
-----------------------------------

Voir Objets, valeurs et types et Définition de classes.


Fonctions
---------

Les objets fonctions sont créés par les définitions de fonctions.  La
seule opération applicable à un objet fonction est de l'appeler :
"func(argument-list)".

Il existe en fait deux catégories d'objets fonctions : les fonctions
natives et les fonctions définies par l'utilisateur. Les deux gèrent
les mêmes opérations (l'appel à la fonction), mais leur implémentation
est différente, d'où les deux types distincts.

Voir Définition de fonctions pour plus d'information.


Méthodes
--------

Methods are functions that are called using the attribute notation.
There are two flavors: built-in methods (such as "append()" on lists)
and class instance method. Built-in methods are described with the
types that support them.

If you access a method (a function defined in a class namespace)
through an instance, you get a special object: a *bound method* (also
called instance method) object. When called, it will add the "self"
argument to the argument list.  Bound methods have two special read-
only attributes: "m.__self__" is the object on which the method
operates, and "m.__func__" is the function implementing the method.
Calling "m(arg-1, arg-2, ..., arg-n)" is completely equivalent to
calling "m.__func__(m.__self__, arg-1, arg-2, ..., arg-n)".

Like function objects, bound method objects support getting arbitrary
attributes.  However, since method attributes are actually stored on
the underlying function object ("method.__func__"), setting method
attributes on bound methods is disallowed.  Attempting to set an
attribute on a method results in an "AttributeError" being raised.  In
order to set a method attribute, you need to explicitly set it on the
underlying function object:

   >>> class C:
   ...     def method(self):
   ...         pass
   ...
   >>> c = C()
   >>> c.method.whoami = 'my name is method'  # can't set on the method
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   AttributeError: 'method' object has no attribute 'whoami'
   >>> c.method.__func__.whoami = 'my name is method'
   >>> c.method.whoami
   'my name is method'

Voir Méthodes d'instances pour plus d'information.


Objets code
-----------

Code objects are used by the implementation to represent "pseudo-
compiled" executable Python code such as a function body. They differ
from function objects because they don't contain a reference to their
global execution environment.  Code objects are returned by the built-
in "compile()" function and can be extracted from function objects
through their "__code__" attribute. See also the "code" module.

L'accès à "__code__" déclenche un événement d'audit
"object.__getattr__" avec les arguments "obj" et ""__code__"".

Les objets code peuvent être exécutés ou évalués en les passant (au
lieu d'une chaîne contenant du code) aux fonctions natives "exec()" ou
"eval()".

Voir Hiérarchie des types standards pour plus d'information.


Objets type
-----------

Les objets types représentent les différents types d'objets. Le type
d'un objet est obtenu via la fonction native "type()". Il n'existe
aucune opération spéciale sur les types. Le module standard "types"
définit les noms de tous les types natifs.

Les types sont affichés comme suit : "<class 'int'>".


L'objet Null
------------

Cet objet est renvoyé par les fonctions ne renvoyant pas explicitement
une valeur. Il ne gère aucune opération spéciale. Il existe exactement
un seul objet *null* nommé "None" (c'est un nom natif). "type(None)()"
produit ce singleton.

Il s'écrit "None".


L'objet points de suspension (ou ellipse)
-----------------------------------------

This object is commonly used to indicate that something is omitted. It
supports no special operations.  There is exactly one ellipsis object,
named "Ellipsis" (a built-in name).  "type(Ellipsis)()" produces the
"Ellipsis" singleton.

Il s'écrit "Ellipsis" ou "...".

In typical use, "..." as the "Ellipsis" object appears in a few
different places, for instance:

* In type annotations, such as callable arguments or tuple elements.

* As the body of a function instead of a pass statement.

* In third-party libraries, such as Numpy's slicing and striding.

Python also uses three dots in ways that are not "Ellipsis" objects,
for instance:

* Doctest's "ELLIPSIS", as a pattern for missing content.

* The default Python prompt of the *interactive* shell when partial
  input is incomplete.

Lastly, the Python documentation often uses three dots in conventional
English usage to mean omitted content, even in code examples that also
use them as the "Ellipsis".


L'objet *NotImplemented*
------------------------

Cet objet est renvoyé depuis des comparaisons ou des opérations
binaires effectuées sur des types qu'elles ne gèrent pas. Voir
Comparaisons pour plus d'informations. Il n'y a qu'un seul objet
"NotImplemented". "type(NotImplemented)()" renvoie cette instance de
singleton.

Il s'écrit "NotImplemented".


Objets internes
---------------

See Hiérarchie des types standards for this information.  It describes
stack frame objects, traceback objects, and slice objects.


Attributs spéciaux
==================

L'implémentation ajoute quelques attributs spéciaux en lecture seule à
certains types, lorsque ça a du sens. Certains ne sont pas listés par
la fonction native "dir()".

definition.__name__

   Nom de la classe, fonction, méthode, descripteur ou instance du
   générateur.

definition.__qualname__

   *Nom qualifié* de la classe, fonction, méthode, descripteur ou
   instance du générateur.

   Ajouté dans la version 3.3.

definition.__module__

   The name of the module in which a class or function was defined.

definition.__doc__

   The documentation string of a class or function, or "None" if
   undefined.

definition.__type_params__

   The type parameters of generic classes, functions, and type
   aliases. For classes and functions that are not generic, this will
   be an empty tuple.

   Ajouté dans la version 3.12.


Limitation de longueur de conversion de chaîne vers un entier
=============================================================

CPython a une limite globale pour la conversion entre "int" et "str"
pour atténuer les attaques par déni de service. Cette limite
s'applique *uniquement* aux décimaux ou autres bases de nombres qui ne
sont pas des puissances de deux. Les conversions hexadécimales,
octales et binaires sont illimitées. La limite peut être configurée.

Le type "int" dans CPython stocke un nombre de longueur arbitraire
sous forme binaire (communément appelé « *bignum* »). Il n'existe
aucun algorithme capable de convertir une chaîne en un entier binaire
ou un entier binaire en une chaîne en temps linéaire, sauf si la base
est une puissance de 2. Même les meilleurs algorithmes connus pour la
base 10 ont une complexité sous-quadratique. La conversion d'une
grande valeur telle que "int('1' * 500_000)" peut prendre plus d'une
seconde sur un CPU rapide.

Limiter la taille de la conversion offre un moyen pratique d'éviter la
vulnérabilité **CVE 2020-10735**.

La limite est appliquée au nombre de caractères numériques dans la
chaîne d'entrée ou de sortie lorsqu'un algorithme de conversion non
linéaire doit être appliqué. Les traits de soulignement et le signe ne
sont pas comptés dans la limite.

Si une opération va dépasser la limite, une "ValueError" est levée :

   >>> import sys
   >>> sys.set_int_max_str_digits(4300)  # Illustrative, this is the default.
   >>> _ = int('2' * 5432)
   Traceback (most recent call last):
   ...
   ValueError: Exceeds the limit (4300 digits) for integer string conversion: value has 5432 digits; use sys.set_int_max_str_digits() to increase the limit
   >>> i = int('2' * 4300)
   >>> len(str(i))
   4300
   >>> i_squared = i*i
   >>> len(str(i_squared))
   Traceback (most recent call last):
   ...
   ValueError: Exceeds the limit (4300 digits) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit
   >>> len(hex(i_squared))
   7144
   >>> assert int(hex(i_squared), base=16) == i*i  # Hexadecimal is unlimited.

La limite par défaut est de 4 300 chiffres comme indiqué dans
"sys.int_info.default_max_str_digits". La limite la plus basse pouvant
être configurée est de 640 chiffres, comme indiqué dans
"sys.int_info.str_digits_check_threshold".

Vérification :

   >>> import sys
   >>> assert sys.int_info.default_max_str_digits == 4300, sys.int_info
   >>> assert sys.int_info.str_digits_check_threshold == 640, sys.int_info
   >>> msg = int('578966293710682886880994035146873798396722250538762761564'
   ...           '9252925514383915483333812743580549779436104706260696366600'
   ...           '571186405732').to_bytes(53, 'big')
   ...

Ajouté dans la version 3.11.


API concernées
--------------

La limitation s'applique uniquement aux conversions potentiellement
lentes entre "int" et "str" ou "bytes" :

* "int(string)" en base 10 (par défaut).

* "int(string, base)" pour toutes les bases qui ne sont pas des
  puissances de 2.

* "str(integer)".

* "repr(integer)".

* toute autre conversion de chaîne en base 10, par exemple
  "f"{integer}"", ""{}".format(integer)" ou "b"%d" % integer".

Les limitations ne s'appliquent pas aux fonctions avec un algorithme
linéaire :

* "int(chaîne, base)" en base 2, 4, 8, 16 ou 32.

* "int.from_bytes()" et "int.to_bytes()".

* "hex()", "oct()", "bin()".

* Mini-langage de spécification de format pour les nombres
  hexadécimaux, octaux et binaires.

* "str" vers "float".

* "str" vers "decimal.Decimal".


Configuration de la limite
--------------------------

Avant le démarrage de Python, vous pouvez utiliser une variable
d'environnement ou une option de ligne de commande d'interpréteur pour
configurer la limite :

* "PYTHONINTMAXSTRDIGITS", par exemple "PYTHONINTMAXSTRDIGITS=640
  python3" pour fixer la limite à 640 chiffres ou
  "PYTHONINTMAXSTRDIGITS=0 python3" pour désactiver la limitation.

* "-X int_max_str_digits", par exemple "python3 -X
  int_max_str_digits=640"

* "sys.flags.int_max_str_digits" contient la valeur de
  "PYTHONINTMAXSTRDIGITS" ou "-X int_max_str_digits". Si la variable
  d'environnement et l'option "-X" sont définies toutes les deux,
  l'option "-X" est prioritaire. Une valeur de *-1* indique que les
  deux n'étaient pas définies, donc qu'une valeur de
  "sys.int_info.default_max_str_digits" a été utilisée lors de
  l'initialisation.

Depuis le code, vous pouvez inspecter la limite actuelle et en définir
une nouvelle à l'aide de ces API "sys" :

* "sys.get_int_max_str_digits()" et "sys.set_int_max_str_digits()"
  sont un accesseur et un mutateur pour la limite relative à
  l'interpréteur. Les sous-interprètes possèdent leur propre limite.

Des informations sur la valeur par défaut et le minimum peuvent être
trouvées dans "sys.int_info" :

* "sys.int_info.default_max_str_digits" est la limite par défaut pour
  la compilation.

* "sys.int_info.str_digits_check_threshold" est la valeur la plus
  basse acceptée pour la limite (autre que 0 qui la désactive).

Ajouté dans la version 3.11.

Prudence:

  fixer une limite basse *peut* entraîner des problèmes. Bien que
  rare, du code contenant des constantes entières en décimal dans la
  source qui dépasse le seuil minimum peut exister. Une conséquence de
  la définition de la limite est que le code source Python contenant
  des littéraux entiers décimaux plus longs que la limite lèvera une
  erreur lors de l'analyse, généralement au démarrage ou à
  l'importation ou même au moment de l'installation – dès qu'un ".pyc"
  à jour n'existe pas déjà pour le code. Une solution de contournement
  pour les sources qui contiennent de si grandes constantes consiste à
  les convertir au format hexadécimal "0x" car il n'y a pas de
  limite.Testez soigneusement votre application si vous utilisez une
  limite basse. Assurez-vous que vos tests s'exécutent avec la limite
  définie au début *via* l'environnement ou l'option de ligne de
  commande afin qu'elle s'applique au démarrage et même lors de toute
  étape d'installation pouvant invoquer Python pour compiler les
  sources ".py" en fichiers ".pyc".


Configuration recommandée
-------------------------

La valeur par défaut "sys.int_info.default_max_str_digits" devrait
être raisonnable pour la plupart des applications. Si votre
application nécessite une limite différente, définissez-la à partir de
votre point d'entrée principal à l'aide d'un code indépendant de la
version Python, car ces API ont été ajoutées dans des correctifs de
sécurité des versions antérieures à 3.12.

Par exemple :

   >>> import sys
   >>> if hasattr(sys, "set_int_max_str_digits"):
   ...     upper_bound = 68000
   ...     lower_bound = 4004
   ...     current_limit = sys.get_int_max_str_digits()
   ...     if current_limit == 0 or current_limit > upper_bound:
   ...         sys.set_int_max_str_digits(upper_bound)
   ...     elif current_limit < lower_bound:
   ...         sys.set_int_max_str_digits(lower_bound)

Pour la désactiver entièrement, réglez-la à "0".

-[ Notes ]-

[1] Plus d'informations sur ces méthodes spéciales peuvent être
    trouvées dans le *Python Reference Manual* (Personnalisation de
    base).

[2] Par conséquent, la liste "[1, 2]" est considérée égale à "[1.0,
    2.0]". Idem avec des *n*-uplets.

[3] Nécessairement, puisque l'analyseur ne peut pas discerner le type
    des opérandes.

[4] Les caractères capitalisables sont ceux dont la propriété Unicode
    *general category* est soit "Lu" (pour *Letter*, *uppercase*),
    soit "Ll" (pour *Letter*, *lowercase*), soit "Lt" (pour *Letter*,
    *titlecase*).

[5] Pour insérer un *n*-uplet, vous devez donc donner un *n*-uplet
    d'un seul élément, contenant le *n*-uplet à insérer.
