csv — Läsning och skrivning av CSV-filer

Källkod: Lib/csv.py


Det s.k. CSV-formatet (Comma Separated Values) är det vanligaste import- och exportformatet för kalkylblad och databaser. CSV-formatet användes under många år innan försök gjordes att beskriva formatet på ett standardiserat sätt i RFC 4180. Avsaknaden av en väldefinierad standard innebär att det ofta finns subtila skillnader i de data som produceras och konsumeras av olika applikationer. Dessa skillnader kan göra det irriterande att bearbeta CSV-filer från flera källor. Även om avgränsnings- och citattecknen varierar är det övergripande formatet ändå tillräckligt likt för att det ska vara möjligt att skriva en enda modul som effektivt kan manipulera sådana data och dölja detaljerna kring läsning och skrivning av data för programmeraren.

Modulen csv implementerar klasser för att läsa och skriva tabelldata i CSV-format. Det gör det möjligt för programmerare att säga ”skriv dessa data i det format som Excel föredrar” eller ”läs data från den här filen som genererades av Excel” utan att känna till de exakta detaljerna i det CSV-format som används av Excel. Programmerare kan också beskriva de CSV-format som förstås av andra applikationer eller definiera sina egna CSV-format för speciella ändamål.

Objekten reader och writer i modulen csv läser och skriver sekvenser. Programmerare kan också läsa och skriva data i ordboksform med hjälp av klasserna DictReader och DictWriter.

Se även

PEP 305 - API för CSV-filer

Python Enhancement Proposal som föreslog detta tillägg till Python.

Modulens innehåll

Modulen csv definierar följande funktioner:

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

Returnerar ett reader object som bearbetar rader från den angivna csvfilen. En csvfile måste vara en iterabel av strängar, var och en i läsarens definierade csv-format. En csvfile är oftast ett filliknande objekt eller en lista. Om csvfile är ett filobjekt bör det öppnas med newline=''. [1] En valfri parameter dialect kan anges som används för att definiera en uppsättning parametrar som är specifika för en viss CSV-dialekt. Den kan vara en instans av en underklass av klassen Dialect eller en av de strängar som returneras av funktionen list_dialects(). De andra valfria fmtparams nyckelordsargumenten kan ges för att åsidosätta enskilda formateringsparametrar i den aktuella dialekten. För fullständig information om dialekt- och formateringsparametrar, se avsnitt Dialekter och formateringsparametrar.

Varje rad som läses från csv-filen returneras som en lista med strängar. Ingen automatisk datatypskonvertering utförs om inte formatalternativet QUOTE_NONNUMERIC anges (i så fall omvandlas fält som inte är citerade till flyttal).

Ett kort exempel på användning:

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

Returnerar ett skrivarobjekt som ansvarar för att konvertera användarens data till avgränsade strängar på det givna filliknande objektet. csvfile kan vara vilket objekt som helst med en write()-metod. Om csvfile är ett filobjekt bör det öppnas med newline='' [1]. En valfri parameter dialect kan anges som används för att definiera en uppsättning parametrar som är specifika för en viss CSV-dialekt. Den kan vara en instans av en underklass till klassen Dialect eller en av de strängar som returneras av funktionen list_dialects(). De andra valfria fmtparams nyckelordsargumenten kan ges för att åsidosätta enskilda formateringsparametrar i den aktuella dialekten. För fullständig information om dialekter och formateringsparametrar, se avsnittet Dialekter och formateringsparametrar. För att göra det så enkelt som möjligt att interagera med moduler som implementerar DB API, skrivs värdet None som den tomma strängen. Även om detta inte är en reversibel transformation, gör det det lättare att dumpa SQL NULL-datavärden till CSV-filer utan att förbehandla de data som returneras från ett cursor.fetch*-anrop. Alla andra data som inte är strängar strängifieras med str() innan de skrivs.

Ett kort exempel på användning:

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

Associera dialekt med namn. name måste vara en sträng. Dialekten kan anges antingen genom att skicka en underklass till Dialect, eller genom fmtparams nyckelordsargument, eller båda, med nyckelordsargument som åsidosätter parametrar för dialekten. För fullständig information om dialekter och formateringsparametrar, se avsnitt Dialekter och formateringsparametrar.

csv.unregister_dialect(name)

Ta bort den dialekt som associeras med namn från dialektregistret. Ett Error visas om namn inte är ett registrerat dialektnamn.

csv.get_dialect(name)

Returnerar den dialekt som associeras med namn. Ett Error visas om namn inte är ett registrerat dialektnamn. Denna funktion returnerar en oföränderlig Dialect.

csv.list_dialects()

Returnera namnen på alla registrerade dialekter.

csv.field_size_limit([new_limit])

Returnerar den aktuella maximala fältstorleken som tillåts av parsern. Om new_limit anges blir detta den nya gränsen.

Modulen csv definierar följande klasser:

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

Skapa ett objekt som fungerar som en vanlig läsare men som mappar informationen i varje rad till en dict vars nycklar anges av den valfria parametern fieldnames.

Parametern fieldnames är en sequence. Om fieldnames utelämnas kommer värdena i den första raden i filen f att användas som fältnamn och utelämnas från resultatet. Om fieldnames anges kommer de att användas och den första raden kommer att inkluderas i resultatet. Oavsett hur fältnamnen bestäms behåller ordlistan deras ursprungliga ordning.

Om en rad har fler fält än fältnamn läggs de återstående uppgifterna i en lista och lagras med det fältnamn som anges av restkey (som har None som standard). Om en rad som inte är blank har färre fält än fältnamn fylls de saknade värdena i med värdet för restval (som har None som standard).

Alla andra valfria argument eller nyckelordsargument skickas till den underliggande reader-instansen.

Om argumentet som skickas till fieldnames är en iterator, kommer det att tvingas till en list.

Ändrad i version 3.6: Returnerade rader är nu av typen OrderedDict.

Ändrad i version 3.8: Returnerade rader är nu av typen dict.

Ett kort exempel på användning:

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

Skapa ett objekt som fungerar som en vanlig skrivare men som mappar ordlistor till utdatarader. Parametern fieldnames är en sequence av nycklar som identifierar i vilken ordning värdena i den ordbok som skickas till writerow()-metoden skrivs till filen f. Den valfria parametern restval anger det värde som ska skrivas om ordlistan saknar en nyckel i fieldnames. Om den ordbok som skickas till writerow()-metoden innehåller en nyckel som inte finns i fieldnames, anger den valfria parametern extrasaction vilken åtgärd som ska vidtas. Om den är inställd på 'raise', standardvärdet, skapas ett ValueError. Om den är inställd på 'ignore' ignoreras extra värden i ordlistan. Alla andra valfria argument eller nyckelordsargument skickas till den underliggande writer-instansen.

Observera att till skillnad från klassen DictReader är parametern fieldnames i klassen DictWriter inte valfri.

Om argumentet som skickas till fieldnames är en iterator, kommer det att tvingas till en list.

Ett kort exempel på användning:

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

Klassen Dialect är en containerklass vars attribut innehåller information om hur man hanterar dubbla citattecken, blanksteg, avgränsare etc. Eftersom det inte finns någon strikt CSV-specifikation producerar olika applikationer subtilt olika CSV-data. Dialect-instanser definierar hur reader- och writer-instanser beter sig.

Alla tillgängliga Dialect-namn returneras av list_dialects(), och de kan registreras med specifika reader- och writer-klasser genom deras initialiseringsfunktioner (__init__) så här:

import csv

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

Klassen excel definierar de vanliga egenskaperna för en Excel-genererad CSV-fil. Den är registrerad med dialektnamnet 'excel.

class csv.excel_tab

Klassen excel_tab definierar de vanliga egenskaperna för en Excel-genererad TAB-delimiterad fil. Den är registrerad med dialektnamnet 'excel-tab.

class csv.unix_dialect

Klassen unix_dialect definierar de vanliga egenskaperna hos en CSV-fil som genereras på UNIX-system, dvs. använder '\n' som radavslutare och citerar alla fält. Den är registrerad med dialektnamnet 'unix.

Tillagd i version 3.2.

class csv.Sniffer

Klassen Sniffer används för att härleda formatet på en CSV-fil.

Klassen Sniffer innehåller två metoder:

sniff(sample, delimiters=None)

Analyserar det givna provet och returnerar en Dialect-underklass som återspeglar de parametrar som hittats. Om den valfria parametern delimiters anges tolkas den som en sträng som innehåller möjliga giltiga avgränsningstecken.

has_header(sample)

Analysera exempeltexten (som antas vara i CSV-format) och returnera True om den första raden verkar vara en serie kolumnrubriker. Genom att inspektera varje kolumn kommer ett av två nyckelkriterier att beaktas för att uppskatta om provet innehåller en rubrik:

  • den andra till n:te raden innehåller numeriska värden

  • de andra till n:te raderna innehåller strängar där minst ett värdes längd skiljer sig från längden på den förmodade rubriken för den kolumnen.

Tjugo rader efter den första raden samplas; om mer än hälften av kolumnerna + raderna uppfyller kriterierna returneras True.

Anteckning

Denna metod är en grov heuristik och kan ge både falska positiva och negativa resultat.

Ett exempel på Sniffer användning:

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

Modulen csv definierar följande konstanter:

csv.QUOTE_ALL

Instruerar writer-objekt att citera alla fält.

csv.QUOTE_MINIMAL

Instruerar writer-objekt att endast citera de fält som innehåller specialtecken som delimiter, quotechar, '\r', '\n' eller något av tecknen i lineterminator.

csv.QUOTE_NONNUMERIC

Instruerar writer-objekt att citera alla icke-numeriska fält.

Instruerar reader-objekt att konvertera alla icke-citerade fält till typen float.

Anteckning

Vissa numeriska typer, t.ex. bool, Fraction eller IntEnum, har en strängrepresentation som inte kan konverteras till float. De kan inte läsas i lägena QUOTE_NONNUMERIC och QUOTE_STRINGS.

csv.QUOTE_NONE

Instruerar writer-objekt att aldrig citera fält. När det aktuella delimiter, quotechar, escapechar, '\r', '\n' eller något av tecknen i lineterminator förekommer i utdata föregås det av det aktuella escapechar tecknet. Om escapechar inte är inställt kommer skrivaren att ge Error om några tecken som kräver escaping påträffas. Sätt quotechar till None för att förhindra att det escapas.

Instruerar reader-objekt att inte utföra någon speciell behandling av citattecken.

csv.QUOTE_NOTNULL

Instruerar writer-objekt att citera alla fält som inte är None. Detta liknar QUOTE_ALL, förutom att om ett fältvärde är None skrivs en tom (ej citerad) sträng.

Instruerar reader-objekt att tolka ett tomt (ej citerat) fält som None och att i övrigt bete sig som QUOTE_ALL.

Tillagd i version 3.12.

csv.QUOTE_STRINGS

Instruerar writer-objekt att alltid placera citattecken runt fält som är strängar. Detta liknar QUOTE_NONNUMERIC, förutom att om ett fältvärde är None skrivs en tom sträng (utan citationstecken).

Instruerar reader-objekt att tolka en tom (ej citerad) sträng som None och att i övrigt bete sig som QUOTE_NONNUMERIC.

Tillagd i version 3.12.

Modulen csv definierar följande undantag:

exception csv.Error

Utlöses av någon av funktionerna när ett fel upptäcks.

Dialekter och formateringsparametrar

För att göra det enklare att ange formatet för in- och utdataposter grupperas specifika formateringsparametrar i dialekter. En dialekt är en underklass till klassen Dialect som innehåller olika attribut som beskriver CSV-filens format. När programmeraren skapar reader- eller writer-objekt kan han ange en sträng eller en underklass av klassen Dialect som dialektparameter. Förutom, eller i stället för, parametern dialekt kan programmeraren också ange individuella formateringsparametrar, som har samma namn som de attribut som definieras nedan för klassen Dialect.

Dialekter stöder följande attribut:

Dialect.delimiter

En sträng med ett tecken som används för att separera fält. Standardvärdet är ','.

Dialect.doublequote

Styr hur förekomster av quotechar som visas inuti ett fält själva ska citeras. När True, dubbleras tecknet. När False används escapechar som prefix till quotechar. Standardvärdet är True.

Om doublequote är False och ingen escapechar har angetts, kommer Error att visas om ett quotechar hittas i ett fält.

Dialect.escapechar

En enteckenssträng som används av skribenten för att undkomma tecken som behöver undkommas:

  • delimiter, quotechar, '\r', '\n' och alla tecken i lineterminator undviks om quoting är satt till QUOTE_NONE;

  • quotechar escapas om doublequote är False;

  • själva escapechar.

Vid läsning tar escapechar bort all speciell betydelse från följande tecken. Standardvärdet är None, vilket inaktiverar escaping.

Ändrad i version 3.11: En tom escapechar är inte tillåten.

Dialect.lineterminator

Den sträng som används för att avsluta rader som produceras av writer. Standardvärdet är '\r\n'.

Anteckning

reader är hårdkodad att känna igen antingen '\r' eller '\n' som radavslut, och ignorerar lineterminator. Detta beteende kan komma att ändras i framtiden.

Dialect.quotechar

En sträng med ett tecken som används för att citera fält som innehåller specialtecken, t.ex. delimiter eller quotechar, eller som innehåller tecken för ny rad ('\r', '\n' eller något av tecknen i lineterminator). Standardvärdet är '"'. Kan sättas till None för att förhindra escaping av '"' om quoting är satt till QUOTE_NONE.

Ändrad i version 3.11: En tom quotechar är inte tillåten.

Dialect.quoting

Styr när citat ska genereras av skribenten och kännas igen av läsaren. Den kan ta någon av QUOTE_*-konstanterna och standardvärdet är QUOTE_MINIMAL om quotechar inte är None, och QUOTE_NONE annars.

Dialect.skipinitialspace

När True ignoreras mellanslag omedelbart efter delimiter. Standardvärdet är False.

Dialect.strict

När True, skapa undantag Error` vid felaktig CSV-data. Standardvärdet är False.

Läsobjekt

Läsarobjekt (DictReader-instanser och objekt som returneras av funktionen reader()) har följande publika metoder:

csvreader.__next__()

Returnerar nästa rad i läsarens iterabla objekt som en lista (om objektet returnerades från reader()) eller en dict (om det är en DictReader-instans), tolkad enligt aktuell Dialect. Vanligtvis bör du anropa detta som next(reader).

Läsarobjekt har följande publika attribut:

csvreader.dialect

En skrivskyddad beskrivning av den dialekt som används av parsern.

csvreader.line_num

Antalet rader som lästs från källans iterator. Detta är inte samma sak som antalet poster som returneras, eftersom poster kan sträcka sig över flera rader.

DictReader-objekt har följande publika attribut:

DictReader.fieldnames

Om attributet inte skickas som en parameter när objektet skapas initieras det vid första åtkomst eller när den första posten läses från filen.

Writer-objekt

writer-objekt (DictWriter-instanser och objekt som returneras av funktionen writer()) har följande publika metoder. En row måste vara en iterabel av strängar eller tal för writer-objekt och en dictionary som mappar fältnamn till strängar eller tal (genom att först skicka dem genom str()) för DictWriter-objekt. Observera att komplexa tal skrivs ut omgivna av parenteser. Detta kan orsaka vissa problem för andra program som läser CSV-filer (förutsatt att de stöder komplexa tal överhuvudtaget).

csvwriter.writerow(row)

Skriv parametern row till skrivarens filobjekt, formaterad enligt aktuell Dialect. Returnera returvärdet för anropet till write-metoden i det underliggande filobjektet.

Ändrad i version 3.5: Lagt till stöd för godtyckliga iterabler.

csvwriter.writerows(rows)

Skriv alla element i rows (en iterabel av row-objekt enligt beskrivningen ovan) till skribentens filobjekt, formaterat enligt den aktuella dialekten.

Writer-objekt har följande publika attribut:

csvwriter.dialect

En skrivskyddad beskrivning av den dialekt som används av skribenten.

DictWriter-objekt har följande publika metod:

DictWriter.writeheader()

Skriver en rad med fältnamnen (som anges i konstruktorn) till skrivarens filobjekt, formaterad enligt den aktuella dialekten. Returnerar returvärdet för csvwriter.writerow()-anropet som används internt.

Tillagd i version 3.2.

Ändrad i version 3.8: writeheader() returnerar nu också det värde som returneras av csvwriter.writerow()-metoden som den använder internt.

Exempel

Det enklaste exemplet på läsning av en CSV-fil:

import csv
med open('some.csv', newline='') som f:
    läsare = csv.läsare(f)
    för rad i reader:
        print(rad)

Läsa en fil med ett alternativt format:

import csv
med open('passwd', newline='') som f:
    reader = csv.reader(f, avgränsare=':', citering=csv.QUOTE_NONE)
    för rad i läsaren:
        print(rad)

Det motsvarande enklaste möjliga skrivningsexemplet är:

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

Eftersom open() används för att öppna en CSV-fil för läsning, kommer filen som standard att avkodas till unicode med hjälp av systemets standardkodning (se locale.getencoding()). Om du vill avkoda en fil med en annan kodning använder du argumentet encoding i open:

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

Detsamma gäller om du vill skriva i något annat än systemets standardkodning: ange kodningsargumentet när du öppnar utdatafilen.

Registrering av en ny dialekt:

import csv
csv.register_dialect('unixpwd', delimiter=':', quoting=csv.QUOTE_NONE)
med open('passwd', newline='') som f:
    läsare = csv.läsare(f, 'unixpwd')

En lite mer avancerad användning av läsaren — att fånga upp och rapportera fel:

import csv, sys
filnamn = 'några.csv'
med open(filnamn, newline='') som f:
    läsare = csv.läsare(f)
    försök:
        för rad i reader:
            print(rad)
    except csv.Error as e:
        sys.exit(f'fil {filename}, rad {reader.line_num}: {e}')

Och även om modulen inte direkt stöder parsning av strängar, kan det enkelt göras:

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

Fotnoter