csv.Dialect
Seven class attributes describe a CSV format. Every reader and writer validates them into an internal _csv.Dialect — single keyword arguments like delimiter=";" override one setting on top of the dialect.
Demo
import csv d = csv.reader([], delimiter=',', quotechar='"').dialect (d.delimiter, d.quotechar, d.escapechar, d.doublequote, d.skipinitialspace, d.quoting, d.lineterminator)
The validation runs when the reader is created: a delimiter must be exactly one character (TypeError otherwise), and delimiter, quotechar and escapechar must differ ("bad delimiter or quotechar value", a ValueError). quotechar=None switches quoting to 3 (QUOTE_NONE) when quoting is not given. A space is a fine delimiter; a space as quotechar or escapechar is only rejected ("bad quotechar value") when skipinitialspace=True. In "subclass", skipinitialspace=True drops the spaces after each delimiter — but not the ones before it.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| delimiter | str (1 char) | no (',') | Separates fields. |
| quotechar | str (1 char) | None | no ('"') | Wraps fields that contain special characters. None turns quoting off (QUOTE_NONE). |
| escapechar | str (1 char) | None | no (None) | Removes the special meaning of the next character (needed with QUOTE_NONE, or doublequote=False). |
| doublequote | bool | no (True) | A quotechar inside a field is written (and read) as two quotechars. |
| skipinitialspace | bool | no (False) | Ignore spaces right after a delimiter when reading. |
| lineterminator | str | no ('\r\n') | Ends rows written by the writer. The reader ignores it: it always accepts \r, \n and \r\n. |
| quoting | int | no (QUOTE_MINIMAL) | One of the six QUOTE_* constants. |
| strict | bool | no (False) | Raise csv.Error on malformed input instead of guessing. |
Return value
class — Subclass it and set the class attributes; pass the class (or a name registered for it) as dialect=.
Common patterns
import csv class Pipes(csv.excel): delimiter = '|' with open('data.psv', newline='', encoding='utf-8') as f: rows = list(csv.reader(f, dialect=Pipes))
import csv class Escaped(csv.excel): quoting = csv.QUOTE_NONE escapechar = '\\' w = csv.writer(f, dialect=Escaped)
import csv reader = csv.reader(f, dialect='excel-tab', skipinitialspace=True)
Examples
Pitfalls
import csv class Semi(csv.Dialect): delimiter = ';' quotechar = '"' lineterminator = '\r\n' list(csv.reader(['a;b'], dialect=Semi))
import csv class Semi(csv.excel): delimiter = ';' list(csv.reader(['a;b'], dialect=Semi))
import csv, io list(csv.reader(io.StringIO('a;b;c', newline=''), lineterminator=';'))
import csv list(csv.reader('a;b;c'.split(';')))
When to use
- A format you read or write in several places
- Bundling several non-default settings under one name
- A single change → pass delimiter=… directly
- Guessing the format of an unknown file → csv.Sniffer
Notes
FAQ
Subclass csv.excel and override the attributes that differ (class Pipes(csv.excel): delimiter = '|'), then pass dialect=Pipes — or csv.register_dialect('pipes', Pipes) and pass dialect='pipes'.