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

**Quellcode:** Lib/csv.py

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

Das sogenannte CSV-Format (Comma Separated Values) ist das gängigste
Import- und Exportformat für Tabellenkalkulationen und Datenbanken.
Das CSV-Format wurde bereits viele Jahre lang verwendet, bevor
versucht wurde, das Format in **RFC 4180** standardisiert zu
beschreiben. Das Fehlen eines klar definierten Standards führt dazu,
dass oft geringfügige Unterschiede in den Daten bestehen, die von
verschiedenen Anwendungen erzeugt und verarbeitet werden. Diese
Unterschiede können die Verarbeitung von CSV-Dateien aus verschiedenen
Quellen erschweren. Dennoch sind die Trennzeichen und
Anführungszeichen zwar unterschiedlich, das Gesamtformat ist jedoch
ähnlich genug, dass es möglich ist, ein einziges Modul zu schreiben,
das solche Daten effizient bearbeiten kann und dabei die Details des
Lesens und Schreibens der Daten vor dem Programmierer verbirgt.

The "csv" module implements classes to read and write tabular data in
CSV format.  It allows programmers to say, "write this data in the
format preferred by Excel," or "read data from this file which was
generated by Excel," without knowing the precise details of the CSV
format used by Excel.  Programmers can also describe the CSV formats
understood by other applications or define their own special-purpose
CSV formats.

The "csv" module's "reader" and "writer" objects read and write
sequences.  Programmers can also read and write data in dictionary
form using the "DictReader" and "DictWriter" classes.

Siehe auch:

  **PEP 305** - CSV-Datei-API
     Der Python Enhancement Proposal, in dem diese Erweiterung für
     Python vorgeschlagen wurde.


Module Contents
===============

The "csv" module defines the following functions:

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

   Return a reader object which will iterate over lines in the given
   *csvfile*. *csvfile* can be any object which supports the
   *iterator* protocol and returns a string each time its "__next__()"
   method is called --- *file objects* and list objects are both
   suitable.   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 Dialects and Formatting
   Parameters.

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

   Ein kurzes Anwendungsbeispiel:

      >>> 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 Dialects and
   Formatting Parameters 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.

   Ein kurzes Anwendungsbeispiel:

      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[, **fmtparams]])

   Ordne *dialect* dem *name* zu. *name* muss eine Zeichenkette sein.
   Der Dialekt kann entweder durch die Übergabe einer Unterklasse von
   "Dialect" oder durch *fmtparams*-Schlüsselwortargumente oder beides
   angegeben werden, wobei Schlüsselwortargumente die Parameter des
   Dialekts überschreiben. Ausführliche Informationen zu Dialekten und
   Formatierungsparametern findest du im Abschnitt Dialects and
   Formatting Parameters.

csv.unregister_dialect(name)

   Löscht den mit *name* verknüpften Dialekt aus dem Dialektregister.
   Es wird eine Ausnahme vom Typ "Error" ausgelöst, wenn *name* kein
   registrierter Dialektname ist.

csv.get_dialect(name)

   Gibt den mit *name* verknüpften Dialekt zurück. Es wird ein Fehler
   vom Typ "Error" ausgelöst, wenn *name* kein registrierter
   Dialektname ist. Diese Funktion gibt ein unveränderliches "Dialect"
   zurück.

csv.list_dialects()

   Gibt die Namen aller registrierten Dialekte zurück.

csv.field_size_limit([new_limit])

   Gibt die aktuell vom Parser zugelassene maximale Feldgröße zurück.
   Wenn *new_limit* angegeben wird, wird dies zur neuen Obergrenze.

The "csv" module defines the following classes:

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

   Erstelle ein Objekt, das wie ein gewöhnlicher Reader funktioniert,
   jedoch die Informationen in jeder Zeile einem "dict" zuordnet,
   dessen Schlüssel durch den optionalen Parameter *fieldnames*
   vorgegeben werden.

   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.  Regardless of how the fieldnames are determined,
   the dictionary preserves their original ordering.

   Wenn eine Zeile mehr Felder enthält als Feldnamen vorhanden sind,
   werden die übrigen Daten in eine Liste aufgenommen und unter dem
   durch *restkey* angegebenen Feldnamen gespeichert (Standardwert ist
   "None"). Wenn eine nicht leere Zeile weniger Felder enthält als
   Feldnamen vorhanden sind, werden die fehlenden Werte mit dem Wert
   von *restval* aufgefüllt (Standardwert ist "None").

   Alle anderen optionalen Argumente oder Schlüsselwortargumente
   werden an die zugrunde liegende Instanz von "reader" übergeben.

   Geändert in Version 3.6: Die zurückgegebenen Zeilen haben nun den
   Typ "OrderedDict".

   Geändert in Version 3.8: Die zurückgegebenen Zeilen haben nun den
   Typ "dict".

   Ein kurzes Anwendungsbeispiel:

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

   Beachte, dass der Parameter *fieldnames* der Klasse "DictWriter" im
   Gegensatz zur Klasse "DictReader" nicht optional ist.

   Ein kurzes Anwendungsbeispiel:

      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

   Die Klasse "Dialect" ist eine Containerklasse, deren Attribute
   Informationen darüber enthalten, wie mit doppelten
   Anführungszeichen, Leerzeichen, Trennzeichen usw. umgegangen werden
   soll. Da es keine strenge CSV-Spezifikation gibt, erzeugen
   verschiedene Anwendungen CSV-Daten, die sich geringfügig
   voneinander unterscheiden. Instanzen von "Dialect" legen fest, wie
   sich Instanzen von "reader" und "writer" verhalten.

   Alle verfügbaren "Dialect"-Namen werden von "list_dialects()"
   zurückgegeben und können über deren Initialisierungsfunktionen
   ("__init__") wie folgt in bestimmten "reader" und "writer"-Klassen
   registriert werden:

      import csv

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

class csv.excel

   Die Klasse "excel" definiert die üblichen Eigenschaften einer von
   Excel erstellten CSV-Datei. Sie ist unter dem Dialektnamen
   "'excel'" registriert.

class csv.excel_tab

   Die Klasse "excel_tab" definiert die üblichen Eigenschaften einer
   von Excel erstellten, durch Tabulatoren getrennten Datei. Sie ist
   unter dem Dialektnamen "'excel-tab'" registriert.

class csv.unix_dialect

   Die Klasse "unix_dialect" definiert die üblichen Eigenschaften
   einer auf UNIX-Systemen erzeugten CSV-Datei, d. h. mit "'\n'" als
   Zeilenabschlusszeichen und Anführungszeichen um alle Felder. Sie
   ist unter dem Dialektnamen "'unix'" registriert.

   Neu in Version 3.2.

class csv.Sniffer

   Die Klasse "Sniffer" dient dazu, das Format einer CSV-Datei zu
   ermitteln.

   Die Klasse "Sniffer" stellt zwei Methoden bereit:

   sniff(sample, delimiters=None)

      Analysiere das angegebene *Beispiel* und gib eine Unterklasse
      von "Dialect" zurück, die die gefundenen Parameter
      widerspiegelt. Wenn der optionale Parameter *delimiters*
      angegeben wird, wird er als Zeichenkette interpretiert, die
      mögliche gültige Trennzeichen enthält.

   has_header(sample)

      Analysiert den Beispieltext (von dem angenommen wird, dass er im
      CSV-Format vorliegt) und gibt "True" zurück, wenn die erste
      Zeile offenbar aus einer Reihe von Spaltenüberschriften besteht.
      Bei der Prüfung jeder Spalte wird eines von zwei zentralen
      Kriterien herangezogen, um abzuschätzen, ob das Beispiel eine
      Kopfzeile enthält:

         * Die zweite bis zur n-ten Zeile enthalten numerische Werte

         * Die zweite bis zur n-ten Zeile enthalten Zeichenfolgen, bei
           denen sich die Länge mindestens eines Werts von der des
           vermeintlichen Kopfes dieser Spalte unterscheidet.

      Twenty rows after the first row are sampled; if more than half
      of columns + rows meet the criteria, "True" is returned.

   Bemerkung:

     Diese Methode ist eine grobe Heuristik und kann sowohl zu falsch-
     positiven als auch zu falsch-negativen Ergebnissen führen.

Ein Beispiel für die Verwendung von "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 ...

The "csv" module defines the following constants:

csv.QUOTE_ALL

   Weist Objekte von "writer" an, alle Felder in Anführungszeichen zu
   setzen.

csv.QUOTE_MINIMAL

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

csv.QUOTE_NONNUMERIC

   Weist Objekte von "writer"  an, alle nicht-numerischen Felder in
   Anführungszeichen zu setzen.

   Instructs the reader to convert all non-quoted fields to type
   *float*.

csv.QUOTE_NONE

   Instructs "writer" objects to never quote fields.  When the current
   *delimiter* 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.

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

The "csv" module defines the following exception:

exception csv.Error

   Wird von einer der Funktionen ausgelöst, wenn ein Fehler erkannt
   wird.


Dialects and Formatting Parameters
==================================

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 having a set of specific
methods and a single "validate()" method.  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.

Dialekte unterstützen die folgenden Attribute:

Dialect.delimiter

   Eine Zeichenkette mit einem Zeichen, die zur Trennung von Feldern
   verwendet wird. Der Standardwert lautet „ "','" “.

Dialect.doublequote

   Legt fest, wie Instanzen von *quotechar*, die innerhalb eines
   Feldes vorkommen, selbst in Anführungszeichen gesetzt werden
   sollen. Bei der Einstellung "True" wird das Zeichen verdoppelt. Bei
   der Einstellung "False" wird das *escapechar* als Präfix vor dem
   *quotechar* verwendet. Die Standardeinstellung ist "True".

   Bei der Ausgabe wird, wenn *doublequote* auf "False" gesetzt ist
   und kein *escapechar* festgelegt wurde, ein "Error" ausgelöst,
   sobald ein *quotechar* in einem Feld gefunden wird.

Dialect.escapechar

   A one-character string used by the writer to escape the *delimiter*
   if *quoting* is set to "QUOTE_NONE" and the *quotechar* if
   *doublequote* is "False". On reading, the *escapechar* removes any
   special meaning from the following character. It defaults to
   "None", which disables escaping.

Dialect.lineterminator

   Die Zeichenkette, mit der die von "writer" erzeugten Zeilen
   abgeschlossen werden. Standardmäßig ist dies "'\r\n'".

   Bemerkung:

     Die Funktion "reader" ist fest so programmiert, dass sie entweder
     "'\r'" oder "'\n'" als Zeilenende erkennt und *lineterminator*
     ignoriert. Dieses Verhalten kann sich in Zukunft ändern.

Dialect.quotechar

   A one-character string used to quote fields containing special
   characters, such as the *delimiter* or *quotechar*, or which
   contain new-line characters.  It defaults to "'"'".

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 (see section Module Contents) and defaults to
   "QUOTE_MINIMAL".

Dialect.skipinitialspace

   When "True", spaces immediately following the *delimiter* are
   ignored. The default is "False".

Dialect.strict

   Wenn "True" gesetzt ist, wird bei fehlerhaften CSV-Eingaben die
   Ausnahme "Error" ausgelöst. Die Standardeinstellung ist "False".


Reader Objects
==============

Reader-Objekte ("DictReader"-Instanzen und Objekte, die von der
Funktion "reader()" zurückgegeben werden) haben die folgenden
öffentlichen Methoden:

csvreader.__next__()

   Gibt die nächste Zeile des iterierbaren Objekts des Readers als
   Liste (falls das Objekt von "reader()" zurückgegeben wurde) oder
   als Dictionary (falls es sich um eine Instanz von "DictReader"
   handelt) zurück, geparst gemäß dem aktuellen "Dialect".
   Normalerweise rufst du dies als "next(reader)" auf.

Reader-Objekte verfügen über die folgenden öffentlichen Attribute:

csvreader.dialect

   Eine schreibgeschützte Beschreibung des vom Parser verwendeten
   Dialekts.

csvreader.line_num

   Die Anzahl der Zeilen, die aus dem Quell-Iterator gelesen wurden.
   Dies ist nicht mit der Anzahl der zurückgegebenen Datensätze
   identisch, da Datensätze sich über mehrere Zeilen erstrecken
   können.

DictReader-Objekte verfügen über das folgende öffentliche Attribut:

DictReader.fieldnames

   Wird dieses Attribut beim Anlegen des Objekts nicht als Parameter
   übergeben, wird es beim ersten Zugriff oder beim Lesen des ersten
   Datensatzes aus der Datei initialisiert.


Writer Objects
==============

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

   Schreibe den Parameter *row* in das Dateiobjekt des Writers,
   formatiert gemäß dem aktuellen "Dialect". Gib den Rückgabewert des
   Aufrufs der Methode *write* des zugrunde liegenden Dateiobjekts
   zurück.

   Geändert in Version 3.5: Unterstützung für beliebige iterierbare
   Objekte hinzugefügt.

csvwriter.writerows(rows)

   Schreibe alle Elemente in *rows* (eine iterierbare Struktur aus
   *row*-Objekten, wie oben beschrieben) in das Dateiobjekt des
   Writers, formatiert gemäß dem aktuellen Dialekts

Writer-Objekte haben die folgende öffentliche Attribut:

csvwriter.dialect

   Eine rein informative Beschreibung des vom Verfasser verwendeten
   Dialekts.

DictWriter-Objekte verfügen über die folgende öffentliche Methode:

DictWriter.writeheader()

   Schreibt eine Zeile mit den Feldnamen (wie im Konstruktor
   angegeben) in das Dateiobjekt des Schreibers, formatiert gemäß dem
   aktuellen Dialekt. Gibt den Rückgabewert des intern verwendeten
   Aufrufs von "csvwriter.writerow()" zurück.

   Neu in Version 3.2.

   Geändert in Version 3.8: "writeheader()" gibt nun auch den Wert
   zurück, den die intern verwendete Methode "csvwriter.writerow()"
   zurückgibt.


Beispiele
=========

Das einfachste Beispiel für das Einlesen einer CSV-Datei:

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

Eine Datei in einem anderen Format lesen:

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

Das entsprechende einfachste Beispiel zum Schreiben lautet:

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

Since "open()" is used to open a CSV file for reading, the file will
by default be decoded into unicode using the system default encoding
(see "locale.getpreferredencoding()").  To decode a file using a
different encoding, use the "encoding" argument of open:

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

The same applies to writing in something other than the system default
encoding: specify the encoding argument when opening the output file.

Einen neuen Dialekt registrieren:

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

Eine etwas fortgeschrittenere Anwendung des Readers – Fehler erkennen
und melden:

   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('file {}, line {}: {}'.format(filename, reader.line_num, e))

Und obwohl das Modul das Parsen von Zeichenketten nicht direkt
unterstützt, lässt sich dies problemlos bewerkstelligen:

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

-[ Fußnoten ]-

[1] If "newline=''" is not specified, newlines embedded inside quoted
    fields will not be interpreted correctly, and on platforms that
    use "\r\n" linendings on write an extra "\r" will be added.  It
    should always be safe to specify "newline=''", since the csv
    module does its own (*universal*) newline handling.
