"csv" --- CSV File Reading and Writing
**************************************

**Code source :** Lib/csv.py

======================================================================

Le format CSV (*Comma Separated Values*, valeurs séparées par des
virgules) est le format le plus commun dans l'importation et
l'exportation de feuilles de calculs et de bases de données.  Le
format fut utilisé pendant des années avant qu'aient lieu des
tentatives de standardisation avec la **RFC 4180**.  L'absence de
format bien défini signifie que des différences subtiles existent dans
la production et la consommation de données par différentes
applications.  Ces différences peuvent gêner lors du traitement de
fichiers CSV depuis des sources multiples. Cependant, bien que les
séparateurs et délimiteurs varient, le format global est suffisamment
similaire pour qu'un module unique puisse manipuler efficacement ces
données, masquant au programmeur les détails de lecture/écriture des
données.

Le module "csv" implémente des classes pour lire et écrire des données
tabulaires au format CSV.  Il vous permet de dire « écris ces données
dans le format préféré par Excel » ou « lis les données de ce fichier
généré par Excel », sans connaître les détails précis du format CSV
utilisé par Excel.  Vous pouvez aussi décrire les formats CSV utilisés
par d'autres applications ou définir vos propres spécialisations.

Les objets "reader" et "writer" du module "csv" lisent et écrivent des
séquences.  Vous pouvez aussi lire/écrire les données dans un
dictionnaire en utilisant les classes "DictReader" et "DictWriter".

Voir aussi:

  **PEP 305** ­— Interface des fichiers CSV
     La proposition d'amélioration de Python (PEP) qui a proposé cet
     ajout au langage.


Contenu du module
=================

Le module "csv" définit les fonctions suivantes :

csv.reader(csvfile, /, dialect='excel', **fmtparams)

   Return a reader object that will process lines from the given
   *csvfile*.  A csvfile must be an iterable of strings, each in the
   reader's defined csv format. A csvfile is most commonly a file-like
   object or list. If *csvfile* is a file object, it should be opened
   with "newline=''". [1]  An optional *dialect* parameter can be
   given which is used to define a set of parameters specific to a
   particular CSV dialect.  It may be an instance of a subclass of the
   "Dialect" class or one of the strings returned by the
   "list_dialects()" function.  The other optional *fmtparams* keyword
   arguments can be given to override individual formatting parameters
   in the current dialect.  For full details about the dialect and
   formatting parameters, see section Dialectes et paramètres de
   formatage.

   Each row read from the csv file is returned as a list of strings.
   No automatic data type conversion is performed unless the
   "QUOTE_NONNUMERIC" format option is specified (in which case
   unquoted fields are transformed into floats).

   Un court exemple d'utilisation :

      >>> import csv
      >>> with open('eggs.csv', newline='') as csvfile:
      ...     spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
      ...     for row in spamreader:
      ...         print(', '.join(row))
      Spam, Spam, Spam, Spam, Spam, Baked Beans
      Spam, Lovely Spam, Wonderful Spam

csv.writer(csvfile, /, dialect='excel', **fmtparams)

   Return a writer object responsible for converting the user's data
   into delimited strings on the given file-like object.  *csvfile*
   can be any object with a "write()" method.  If *csvfile* is a file
   object, it should be opened with "newline=''" [1].  An optional
   *dialect* parameter can be given which is used to define a set of
   parameters specific to a particular CSV dialect.  It may be an
   instance of a subclass of the "Dialect" class or one of the strings
   returned by the "list_dialects()" function.  The other optional
   *fmtparams* keyword arguments can be given to override individual
   formatting parameters in the current dialect.  For full details
   about dialects and formatting parameters, see the Dialectes et
   paramètres de formatage section. To make it as easy as possible to
   interface with modules which implement the DB API, the value "None"
   is written as the empty string.  While this isn't a reversible
   transformation, it makes it easier to dump SQL NULL data values to
   CSV files without preprocessing the data returned from a
   "cursor.fetch*" call. All other non-string data are stringified
   with "str()" before being written.

   Un court exemple d'utilisation :

      import csv
      with open('eggs.csv', 'w', newline='') as csvfile:
          spamwriter = csv.writer(csvfile, delimiter=' ',
                                  quotechar='|', quoting=csv.QUOTE_MINIMAL)
          spamwriter.writerow(['Spam'] * 5 + ['Baked Beans'])
          spamwriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])

csv.register_dialect(name, /, dialect='excel', **fmtparams)

   Associe *dialect* avec *name*.  *name* doit être une chaîne de
   caractères. Le dialecte peut être spécifié en passant une instance
   d'une sous-classe de "Dialect", des arguments nommés *fmtparams*,
   ou les deux, avec les arguments nommés redéfinissant les paramètres
   du dialecte. Pour tous les détails sur les dialectes et paramètres
   de formatage, voir la section Dialectes et paramètres de formatage.

csv.unregister_dialect(name)

   Supprime le dialecte associé à *name* depuis le registre des
   dialectes.  Une "Error" est levée si *name* n'est pas un nom de
   dialecte enregistré.

csv.get_dialect(name)

   Renvoie le dialecte associé à *name*.  Une "Error" est levée si
   *name* n'est pas un nom de dialecte enregistré.  Cette fonction
   renvoie un objet "Dialect" immuable.

csv.list_dialects()

   Renvoie les noms de tous les dialectes enregistrés.

csv.field_size_limit()
csv.field_size_limit(new_limit)

   Renvoie la taille de champ maximale actuelle autorisée par
   l'analyseur. Si *new_limit* est donnée, elle devient la nouvelle
   limite.

Le module "csv" définit les classes suivantes :

class csv.DictReader(f, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)

   Crée un objet qui opère comme un lecteur ordinaire mais assemble
   les informations de chaque ligne dans un "dict" dont les clés sont
   données par le paramètre optionnel *fieldnames*.

   The *fieldnames* parameter is a *sequence*.  If *fieldnames* is
   omitted, the values in the first row of file *f* will be used as
   the fieldnames and will be omitted from the results. If
   *fieldnames* is provided, they will be used and the first row will
   be included in the results.  Regardless of how the fieldnames are
   determined, the dictionary preserves their original ordering.

   Si une ligne a plus de champs que *fieldnames*, les données
   excédentaires sont mises dans une liste stockée dans le champ
   spécifié par *restkey* ("None" par défaut).  Si une ligne non-vide
   a moins de champs que *fieldnames*, les valeurs manquantes sont
   remplacées par la valeur de *restval* ("None" par défaut).

   Tous les autres arguments optionnels ou nommés sont passés à
   l'instance "reader" sous-jacente.

   If the argument passed to *fieldnames* is an iterator, it will be
   coerced to a "list".

   Modifié dans la version 3.6: Les lignes renvoyées sont maintenant
   de type "OrderedDict".

   Modifié dans la version 3.8: Les lignes renvoyées sont maintenant
   de type "dict".

   Un court exemple d'utilisation :

      >>> import csv
      >>> with open('names.csv', newline='') as csvfile:
      ...     reader = csv.DictReader(csvfile)
      ...     for row in reader:
      ...         print(row['first_name'], row['last_name'])
      ...
      Eric Idle
      John Cleese

      >>> print(row)
      {'first_name': 'John', 'last_name': 'Cleese'}

class csv.DictWriter(f, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds)

   Create an object which operates like a regular writer but maps
   dictionaries onto output rows.  The *fieldnames* parameter is a
   "sequence" of keys that identify the order in which values in the
   dictionary passed to the "writerow()" method are written to file
   *f*.  The optional *restval* parameter specifies the value to be
   written if the dictionary is missing a key in *fieldnames*.  If the
   dictionary passed to the "writerow()" method contains a key not
   found in *fieldnames*, the optional *extrasaction* parameter
   indicates what action to take. If it is set to "'raise'", the
   default value, a "ValueError" is raised. If it is set to
   "'ignore'", extra values in the dictionary are ignored. Any other
   optional or keyword arguments are passed to the underlying "writer"
   instance.

   Notez que contrairement à la classe "DictReader", le paramètre
   *fieldnames* de "DictWriter" n'est pas optionnel.

   If the argument passed to *fieldnames* is an iterator, it will be
   coerced to a "list".

   Un court exemple d'utilisation :

      import csv

      with open('names.csv', 'w', newline='') as csvfile:
          fieldnames = ['first_name', 'last_name']
          writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

          writer.writeheader()
          writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})
          writer.writerow({'first_name': 'Lovely', 'last_name': 'Spam'})
          writer.writerow({'first_name': 'Wonderful', 'last_name': 'Spam'})

class csv.Dialect

   La classe "Dialect" est une classe dont les attributs contiennent
   des informations sur la façon de gérer les guillemets, les espaces,
   les délimiteurs, etc. En raison de l’absence d’une spécification
   CSV stricte, différentes applications produisent des données CSV
   subtilement différentes. Les instances "Dialect" définissent le
   comportement des instances "reader" et "writer".

   Tous les noms disponibles de "Dialect" sont renvoyés par
   "list_dialects()", et ils peuvent être enregistrés avec des classes
   "reader" et "writer" spécifiques en passant par leur fonction
   d’initialisation ("__init__") comme ici :

      import csv

      with open('students.csv', 'w', newline='') as csvfile:
          writer = csv.writer(csvfile, dialect='unix')

class csv.excel

   La classe "excel" définit les propriétés usuelles d'un fichier CSV
   généré par Excel.  Elle est enregistrée avec le nom de dialecte
   "'excel'".

class csv.excel_tab

   La classe "excel_tab" définit les propriétés usuelles d'un fichier
   CSV généré par Excel avec des tabulations comme séparateurs.  Elle
   est enregistrée avec le nom de dialecte "'excel-tab'".

class csv.unix_dialect

   La classe "unix_dialect" définit les propriétés usuelles d'un
   fichier CSV généré sur un système Unix, c'est-à-dire utilisant
   "'\n'" comme marqueur de fin de ligne et délimitant tous les champs
   par des guillemets.  Elle est enregistrée avec le nom de dialecte
   "'unix'".

   Ajouté dans la version 3.2.

class csv.Sniffer

   La classe "Sniffer" est utilisée pour déduire le format d'un
   fichier CSV.

   La classe "Sniffer" fournit deux méthodes :

   sniff(sample, delimiters=None)

      Analyse l'extrait donné (*sample*) et renvoie une sous-classe
      "Dialect" reflétant les paramètres trouvés.  Si le paramètre
      optionnel *delimiters* est donné, il est interprété comme une
      chaîne contenant tous les caractères valides de séparation
      possibles.

   has_header(sample)

      Analyse l'extrait de texte (présumé être au format CSV) et
      renvoie "True" si la première ligne semble être une série d'en-
      têtes de colonnes. En inspectant chaque colonne, l’un des deux
      critères clés sera pris en compte pour estimer si l’échantillon
      contient un en-tête :

      * les deuxième à n-ième lignes contiennent des valeurs
        numériques

      * les deuxième à n-ième lignes contiennent des chaînes dont la
        longueur d’au moins une valeur diffère de celle de l’en-tête
        putatif de cette colonne.

      L'échantillon est composé des vingt lignes après la première
      ligne ; si plus de la moitié des colonnes + lignes répondent aux
      critères, "True" est renvoyé.

   Note:

     Cette méthode est une heuristique discutable et peut produire
     tant des faux-positifs que des faux-négatifs.

Un exemple d'utilisation de "Sniffer" :

   with open('example.csv', newline='') as csvfile:
       dialect = csv.Sniffer().sniff(csvfile.read(1024))
       csvfile.seek(0)
       reader = csv.reader(csvfile, dialect)
       # ... process CSV file contents here ...

Le module "csv" définit les constantes suivantes :

csv.QUOTE_ALL

   Indique aux objets "writer" de délimiter tous les champs par des
   guillemets.

csv.QUOTE_MINIMAL

   Instructs "writer" objects to only quote those fields which contain
   special characters such as *delimiter*, *quotechar*, "'\r'", "'\n'"
   or any of the characters in *lineterminator*.

csv.QUOTE_NONNUMERIC

   Indique aux objets "writer" de délimiter ainsi tous les champs non-
   numériques.

   Instructs "reader" objects to convert all non-quoted fields to type
   "float".

   Note:

     Some numeric types, such as "bool", "Fraction", or "IntEnum",
     have a string representation that cannot be converted to "float".
     They cannot be read in the "QUOTE_NONNUMERIC" and "QUOTE_STRINGS"
     modes.

csv.QUOTE_NONE

   Instructs "writer" objects to never quote fields. When the current
   *delimiter*, *quotechar*, *escapechar*, "'\r'", "'\n'" or any of
   the characters in *lineterminator* occurs in output data it is
   preceded by the current *escapechar* character. If *escapechar* is
   not set, the writer will raise "Error" if any characters that
   require escaping are encountered. Set *quotechar* to "None" to
   prevent its escaping.

   Instructs "reader" objects to perform no special processing of
   quote characters.

csv.QUOTE_NOTNULL

   Instructs "writer" objects to quote all fields which are not
   "None".  This is similar to "QUOTE_ALL", except that if a field
   value is "None" an empty (unquoted) string is written.

   Instructs "reader" objects to interpret an empty (unquoted) field
   as "None" and to otherwise behave as "QUOTE_ALL".

   Ajouté dans la version 3.12.

csv.QUOTE_STRINGS

   Instructs "writer" objects to always place quotes around fields
   which are strings.  This is similar to "QUOTE_NONNUMERIC", except
   that if a field value is "None" an empty (unquoted) string is
   written.

   Instructs "reader" objects to interpret an empty (unquoted) string
   as "None" and to otherwise behave as "QUOTE_NONNUMERIC".

   Ajouté dans la version 3.12.

Le module "csv" définit les exceptions suivantes :

exception csv.Error

   Levée par les fonctions du module quand une erreur détectée.


Dialectes et paramètres de formatage
====================================

To make it easier to specify the format of input and output records,
specific formatting parameters are grouped together into dialects.  A
dialect is a subclass of the "Dialect" class containing various
attributes describing the format of the CSV file.  When creating
"reader" or "writer" objects, the programmer can specify a string or a
subclass of the "Dialect" class as the dialect parameter.  In addition
to, or instead of, the *dialect* parameter, the programmer can also
specify individual formatting parameters, which have the same names as
the attributes defined below for the "Dialect" class.

Les dialectes supportent les attributs suivants :

Dialect.delimiter

   Une chaîne d'un seul caractère utilisée pour séparer les champs.
   Elle vaut "','" par défaut.

Dialect.doublequote

   Contrôle comment les caractères *quotechar* dans le champ doivent
   être retranscrits.  Quand ce paramètre vaut "True", le caractère
   est doublé. Quand il vaut "False", le caractère *escapechar* est
   utilisé comme préfixe à *quotechar*.  Il vaut "True" par défaut.

   En écriture, si *doublequote* vaut "False" et qu'aucun *escapechar*
   n'est précisé, une "Error" est levée si un *quotechar* est trouvé
   dans le champ.

Dialect.escapechar

   A one-character string used by the writer to escape characters that
   require escaping:

      * the *delimiter*, the *quotechar*, "'\r'", "'\n'" and any of
        the characters in *lineterminator* are escaped if *quoting* is
        set to "QUOTE_NONE";

      * the *quotechar* is escaped if *doublequote* is "False";

      * the *escapechar* itself.

   On reading, the *escapechar* removes any special meaning from the
   following character. It defaults to "None", which disables
   escaping.

   Modifié dans la version 3.11: Un "escapechar" vide n'est pas
   autorisé.

Dialect.lineterminator

   La chaîne utilisée pour terminer les lignes produites par un
   "writer". Elle vaut par défaut "'\r\n'".

   Note:

     La classe "reader" est codée en dur pour reconnaître "'\r'" et
     "'\n'" comme marqueurs de fin de ligne, et ignorer
     *lineterminator*. Ce comportement pourrait changer dans le futur.

Dialect.quotechar

   A one-character string used to quote fields containing special
   characters, such as the *delimiter* or the *quotechar*, or which
   contain new-line characters ("'\r'", "'\n'" or any of the
   characters in *lineterminator*). It defaults to "'"'". Can be set
   to "None" to prevent escaping "'"'" if *quoting* is set to
   "QUOTE_NONE".

   Modifié dans la version 3.11: Un "quotechar" vide n'est pas
   autorisé.

Dialect.quoting

   Controls when quotes should be generated by the writer and
   recognised by the reader.  It can take on any of the QUOTE_*
   constants and defaults to "QUOTE_MINIMAL" if *quotechar* is not
   "None", and "QUOTE_NONE" otherwise.

Dialect.skipinitialspace

   Quand il vaut "True", les espaces suivant directement *delimiter*
   sont ignorés. Il vaut "False" par défaut.

Dialect.strict

   Quand il vaut "True", une exception "Error" est levée lors de
   mauvaises entrées CSV. Il vaut "False" par défaut.


Objets lecteurs
===============

Les objets lecteurs (instances de "DictReader" ou objets renvoyés par
la fonction "reader()") ont les méthodes publiques suivantes :

csvreader.__next__()

   Renvoie la ligne suivante de l'objet itérable du lecteur en tant
   que liste (si l'objet est renvoyé depuis "reader()") ou
   dictionnaire (si l'objet est un "DictReader"), analysé suivant la
   classe "Dialect" utilisée. Généralement, vous devez appeler la
   méthode à l'aide de "next(reader)".

Les objets lecteurs ont les attributs publics suivants :

csvreader.dialect

   Une description en lecture seule du dialecte utilisé par
   l'analyseur.

csvreader.line_num

   Le nombre de lignes lues depuis l'itérateur source. Ce n'est pas
   équivalent au nombre d'enregistrements renvoyés, puisque certains
   enregistrements peuvent s'étendre sur plusieurs lignes.

Les objets *DictReader* ont les attributs publics suivants :

DictReader.fieldnames

   S'il n'est pas passé comme paramètre à la création de l'objet, cet
   attribut est initialisé lors du premier accès ou quand le premier
   enregistrement est lu depuis le fichier.


Objets transcripteurs
=====================

"writer" objects ("DictWriter" instances and objects returned by the
"writer()" function) have the following public methods.  A *row* must
be an iterable of strings or numbers for "writer" objects and a
dictionary mapping fieldnames to strings or numbers (by passing them
through "str()" first) for "DictWriter" objects.  Note that complex
numbers are written out surrounded by parens. This may cause some
problems for other programs which read CSV files (assuming they
support complex numbers at all).

csvwriter.writerow(row, /)

   Écrit le paramètre *row* vers l’objet fichier du transcripteur,
   formaté selon la classe "Dialect" utilisée. Renvoie la valeur de
   retour de l'appel à la méthode *write* de l'objet fichier sous-
   jacent.

   Modifié dans la version 3.5: Ajout du support d'itérables
   arbitraires.

csvwriter.writerows(rows, /)

   Écrit tous les éléments de *rows* (itérable d'objets *row* comme
   décrits précédemment) vers le fichier associé au transcripteur,
   formatés selon le dialecte utilisé.

Les objets transcripteurs ont l’attribut public suivant :

csvwriter.dialect

   Une description en lecture seule du dialecte utilisé par le
   transcripteur.

Les objets *DictWriter* ont la méthode publique suivante :

DictWriter.writeheader()

   Écrit une ligne avec le nom des en-têtes (comme définies dans le
   constructeur) dans l'objet fichier associé au transcripteur,
   formatée selon le dialecte utilisé. Renvoie la valeur de retour de
   l'appel "csvwriter.writerow()" utilisé en interne.

   Ajouté dans la version 3.2.

   Modifié dans la version 3.8: "writeheader()" renvoie maintenant
   aussi la valeur renvoyée par la méthode "csvwriter.writerow()"
   qu'il utilise en interne.


Exemples
========

Le plus simple exemple de lecture d'un fichier CSV :

   import csv
   with open('some.csv', newline='') as f:
       reader = csv.reader(f)
       for row in reader:
           print(row)

Lire un fichier avec un format alternatif :

   import csv
   with open('passwd', newline='') as f:
       reader = csv.reader(f, delimiter=':', quoting=csv.QUOTE_NONE)
       for row in reader:
           print(row)

Le plus simple exemple d'écriture correspondant est :

   import csv
   with open('some.csv', 'w', newline='') as f:
       writer = csv.writer(f)
       writer.writerows(someiterable)

Puisque "open()" est utilisée pour ouvrir un fichier CSV en lecture,
le fichier sera par défaut décodé vers Unicode en utilisant l'encodage
par défaut (voir "locale.getencoding()").  Pour décoder un fichier
utilisant un encodage différent, utilisez l'argument "encoding" de
*open* :

   import csv
   with open('some.csv', newline='', encoding='utf-8') as f:
       reader = csv.reader(f)
       for row in reader:
           print(row)

Cela s’applique également lors de l'écriture dans un autre encodage
que celui par défaut du système : spécifiez l'encodage en argument
lors de l'ouverture du fichier de sortie.

Enregistrer un nouveau dialecte :

   import csv
   csv.register_dialect('unixpwd', delimiter=':', quoting=csv.QUOTE_NONE)
   with open('passwd', newline='') as f:
       reader = csv.reader(f, 'unixpwd')

Un exemple d'utilisation un peu plus avancé du lecteur --- attrapant
et notifiant les erreurs :

   import csv, sys
   filename = 'some.csv'
   with open(filename, newline='') as f:
       reader = csv.reader(f)
       try:
           for row in reader:
               print(row)
       except csv.Error as e:
           sys.exit(f'file {filename}, line {reader.line_num}: {e}')

Et bien que le module ne permette pas d'analyser directement des
chaînes, cela peut être fait facilement :

   import csv
   for row in csv.reader(['one,two,three']):
       print(row)

-[ Notes ]-

[1] Si "newline=''" n'est pas précisé, les caractères de fin de ligne
    embarqués dans des champs délimités par des guillemets ne seront
    pas interprétés correctement, et sur les plateformes qui utilisent
    "\r\n" comme marqueur de fin de ligne, un "\r" sera ajouté. Il
    devrait toujours être sûr de préciser "newline=''", puisque le
    module *csv* gère lui-même les fins de lignes (*universelles*).
