csv — Чтение и запись файлов CSV

Исходный код: Lib/csv.py.


Так называемый формат CSV (Comma Separated Values) является наиболее распространенным форматом импорта и экспорта для электронных таблиц и баз данных. Формат CSV использовался в течение многих лет до попыток стандартизированного описания формата в RFC 4180. Отсутствие четко определенного стандарта означает, что в данных, создаваемых и потребляемых различными приложениями, часто существуют тонкие различия. Эти различия могут вызвать раздражение при обработке CSV-файлов из нескольких источников. Тем не менее, хотя разделители и символы цитирования различны, общий формат достаточно похож, чтобы можно было написать единый модуль, который может эффективно манипулировать такими данными, скрывая от программиста детали чтения и записи данных.

Модуль csv реализует классы для чтения и записи табличных данных в формате CSV. Он позволяет программистам сказать: «запишите эти данные в формате, предпочитаемом Excel» или «прочитайте данные из этого файла, который был сгенерирован Excel», не зная точных деталей формата CSV, используемого Excel. Программисты также могут описать форматы CSV, понимаемые другими приложениями, или определить свои собственные специализированные форматы CSV.

Объекты csv модуля reader и writer читают и записывают последовательности. Программисты также могут читать и записывать данные в словарной форме с помощью классов DictReader и DictWriter.

См.также

PEP 305 - CSV File API

Python Enhancement Proposal, в котором предлагалось это дополнение к Python.

Содержание модуля

Модуль csv определяет следующие функции:

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

Возвращает объект читателя, который будет перебирать строки в заданном csvfile. csvfile может быть любым объектом, который поддерживает протокол iterator и возвращает строку каждый раз, когда вызывается его метод __next__()file objects и объекты списка подходят. Если csvfile является файловым объектом, его следует открыть с помощью newline=''. 1 Может быть задан необязательный параметр dialect, который используется для определения набора параметров, специфичных для определенного диалекта CSV. Это может быть экземпляр подкласса класса Dialect или одна из строк, возвращаемых функцией list_dialects(). Другие необязательные аргументы ключевого слова fmtparams могут быть заданы для переопределения отдельных параметров форматирования в текущем диалекте. Подробную информацию о диалекте и параметрах форматирования см. в разделе Диалекты и параметры форматирования.

Каждая строка, считанная из файла csv, возвращается в виде списка строк. Автоматическое преобразование типов данных не выполняется, если не указана опция формата QUOTE_NONNUMERIC (в этом случае поля без кавычек преобразуются в плавающие).

Краткий пример использования:

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

Возвращает объект writer, отвечающий за преобразование данных пользователя в разделенные строки на заданном файлоподобном объекте. csvfile может быть любым объектом с методом write(). Если csvfile является файловым объектом, он должен быть открыт методом newline='' 1. Может быть задан необязательный параметр dialect, который используется для определения набора параметров, специфичных для определенного диалекта CSV. Это может быть экземпляр подкласса класса Dialect или одна из строк, возвращаемых функцией list_dialects(). Другие необязательные аргументы ключевого слова fmtparams могут быть заданы для переопределения отдельных параметров форматирования в текущем диалекте. Подробную информацию о диалектах и параметрах форматирования см. в разделе Диалекты и параметры форматирования. Чтобы максимально упростить взаимодействие с модулями, реализующими DB API, значение None записывается как пустая строка. Хотя это не обратимое преобразование, оно облегчает сброс значений данных SQL NULL в файлы CSV без предварительной обработки данных, возвращаемых вызовом cursor.fetch*. Все остальные нестроковые данные перед записью подвергаются строковой обработке с помощью str().

Краткий пример использования:

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

Ассоциировать диалект с именем. Имя должно быть строкой. Диалект может быть указан либо передачей подкласса Dialect, либо аргументами ключевого слова fmtparams, либо обоими аргументами, причем аргументы ключевого слова переопределяют параметры диалекта. Подробную информацию о диалектах и параметрах форматирования см. в разделе Диалекты и параметры форматирования.

csv.unregister_dialect(name)

Удалить диалект, связанный с name, из реестра диалектов. Если name не является зарегистрированным именем диалекта, выдается сообщение Error.

csv.get_dialect(name)

Возвращает диалект, связанный с name. Если name не является зарегистрированным именем диалекта, выдается сообщение Error. Эта функция возвращает неизменяемый Dialect.

csv.list_dialects()

Возвращает имена всех зарегистрированных диалектов.

csv.field_size_limit([new_limit])

Возвращает текущий максимальный размер поля, разрешенный синтаксическим анализатором. Если задано new_limit, это значение становится новым пределом.

Модуль csv определяет следующие классы:

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

Создайте объект, который работает как обычный читатель, но отображает информацию в каждой строке в dict, ключи которого задаются необязательным параметром fieldnames.

Параметр fieldnames представляет собой sequence. Если fieldnames опущен, то в качестве имен полей будут использоваться значения в первой строке файла f. Независимо от того, как определяются имена полей, словарь сохраняет их исходный порядок.

Если в строке больше полей, чем имен полей, оставшиеся данные помещаются в список и хранятся с именем поля, заданным restkey (по умолчанию None). Если непустая строка имеет меньше полей, чем имен полей, недостающие значения заполняются значением restval (по умолчанию None).

Все остальные необязательные аргументы или ключевые слова передаются базовому экземпляру reader.

Изменено в версии 3.6: Возвращаемые строки теперь имеют тип OrderedDict.

Изменено в версии 3.8: Возвращаемые строки теперь имеют тип dict.

Краткий пример использования:

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

Создайте объект, который работает как обычный писатель, но отображает словари на выходные строки. Параметр fieldnames представляет собой sequence ключей, определяющих порядок, в котором значения в словаре, переданном методу writerow(), записываются в файл f. Необязательный параметр restval определяет значение, которое будет записано, если в словаре отсутствует ключ в fieldnames. Если словарь, переданный методу writerow(), содержит ключ, не найденный в fieldnames, необязательный параметр extrasaction указывает, какое действие следует предпринять. Если он установлен в 'raise', значение по умолчанию, то будет выдано предупреждение ValueError. Если он имеет значение 'ignore', дополнительные значения в словаре игнорируются. Любые другие необязательные аргументы или ключевые слова передаются базовому экземпляру writer.

Обратите внимание, что в отличие от класса DictReader, параметр fieldnames класса DictWriter не является необязательным.

Краткий пример использования:

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

Класс Dialect - это контейнерный класс, атрибуты которого содержат информацию о том, как работать с двойными кавычками, пробелами, разделителями и т.д. Из-за отсутствия строгой спецификации CSV, различные приложения создают существенно отличающиеся данные CSV. Экземпляры Dialect определяют поведение экземпляров reader и writer.

Все доступные имена Dialect возвращаются функцией list_dialects(), и они могут быть зарегистрированы с определенными классами reader и writer через их инициализаторы (__init__), например, так:

import csv

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

Класс excel определяет обычные свойства генерируемого Excel файла CSV. Он зарегистрирован с именем диалекта 'excel'.

class csv.excel_tab

Класс excel_tab определяет обычные свойства генерируемого Excel TAB-разделенного файла. Он зарегистрирован с именем диалекта 'excel-tab'.

class csv.unix_dialect

Класс unix_dialect определяет обычные свойства CSV-файла, создаваемого в UNIX-системах, т.е. использование '\n' в качестве терминатора строк и цитирование всех полей. Он зарегистрирован с именем диалекта 'unix'.

Добавлено в версии 3.2.

class csv.Sniffer

Класс Sniffer используется для вывода формата файла CSV.

Класс Sniffer предоставляет два метода:

sniff(sample, delimiters=None)

Анализирует заданный образец и возвращает подкласс Dialect, отражающий найденные параметры. Если задан необязательный параметр delimiters, он интерпретируется как строка, содержащая возможные допустимые символы-разделители.

has_header(sample)

Проанализируйте текст образца (предположительно в формате CSV) и верните True, если первая строка окажется серией заголовков столбцов. При осмотре каждого столбца будет учитываться один из двух ключевых критериев, чтобы определить, содержит ли образец заголовок:

  • со второй по n-ую строки содержат числовые значения

  • со второй по n-ую строки содержат строки, в которых длина по крайней мере одного значения отличается от длины предполагаемого заголовка этого столбца.

Двадцать строк после первой строки подвергаются выборке; если более половины столбцов + строк удовлетворяют критериям, возвращается True.

Примечание

Этот метод является грубой эвристикой и может давать как ложные положительные, так и отрицательные результаты.

Пример для использования 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 ...

Модуль csv определяет следующие константы:

csv.QUOTE_ALL

Указывает объектам writer заключать все поля в кавычки.

csv.QUOTE_MINIMAL

Предписывает объектам writer заключать в кавычки только те поля, которые содержат специальные символы, такие как delimiter, quotechar или любой из символов в lineterminator.

csv.QUOTE_NONNUMERIC

Указывает объектам writer заключать в кавычки все нечисловые поля.

Указывает читателю преобразовать все некавычки в тип float.

csv.QUOTE_NONE

Указывает объектам writer никогда не заключать поля в кавычки. Когда в выходных данных встречается текущий разделитель, ему предшествует текущий символ escapechar. Если escapechar не установлен, то при появлении любых символов, требующих экранирования, программа записи выдаст сообщение Error.

Указывает reader не выполнять специальную обработку символов кавычек.

Модуль csv определяет следующее исключение:

exception csv.Error

Вызывается любой из функций при обнаружении ошибки.

Диалекты и параметры форматирования

Чтобы облегчить определение формата входных и выходных записей, специфические параметры форматирования объединяются в диалекты. Диалект - это подкласс класса Dialect, имеющий набор специфических методов и один метод validate(). При создании объектов reader или writer программист может указать в качестве параметра диалекта строку или подкласс класса Dialect. В дополнение к параметру диалект или вместо него программист может указать отдельные параметры форматирования, которые имеют те же имена, что и атрибуты, определенные ниже для класса Dialect.

Диалекты поддерживают следующие атрибуты:

Dialect.delimiter

Односимвольная строка, используемая для разделения полей. По умолчанию имеет значение ','.

Dialect.doublequote

Определяет, как должны заключаться в кавычки экземпляры quotechar, появляющиеся внутри поля. Когда True, символ удваивается. Когда False, escapechar используется как префикс к quotechar. По умолчанию используется значение True.

При выводе, если doublequote имеет значение False и не задан escapechar, то при обнаружении в поле quotechar будет выдано сообщение Error.

Dialect.escapechar

Односимвольная строка, используемая пишущей программой для удаления разделителя, если кавычки установлены в QUOTE_NONE, и кавычек, если двойные кавычки установлены в False. При чтении escapechar удаляет любое специальное значение из следующего символа. По умолчанию он имеет значение None, что отключает экранирование.

Dialect.lineterminator

Строка, используемая для завершения строк, создаваемых командой writer. По умолчанию используется '\r\n'.

Примечание

reader жестко закодирован для распознавания либо '\r', либо '\n' как конца строки, и игнорирует линейный определитель. Это поведение может измениться в будущем.

Dialect.quotechar

Односимвольная строка, используемая для цитирования полей, содержащих специальные символы, такие как delimiter или quotechar, или содержащих символы новой строки. По умолчанию это значение равно '"'.

Dialect.quoting

Определяет, когда кавычки должны генерироваться писателем и распознаваться читателем. Он может принимать значение любой из констант QUOTE_* (см. раздел Содержание модуля) и по умолчанию имеет значение QUOTE_MINIMAL.

Dialect.skipinitialspace

Если True, пробельные символы, следующие сразу за разделителем, игнорируются. По умолчанию используется False.

Dialect.strict

Если True, вызывает исключение Error при плохом вводе CSV. По умолчанию используется False.

Объекты для чтения

Объекты Reader (экземпляры DictReader и объекты, возвращаемые функцией reader()) имеют следующие публичные методы:

csvreader.__next__()

Возвращает следующую строку объекта iterable читателя в виде списка (если объект был возвращен из reader()) или dict (если это экземпляр DictReader), разобранный в соответствии с текущим Dialect. Обычно вы должны вызывать это как next(reader).

Объекты Reader имеют следующие публичные атрибуты:

csvreader.dialect

Описание диалекта, используемого синтаксическим анализатором, доступное только для чтения.

csvreader.line_num

Количество строк, прочитанных из исходного итератора. Это не то же самое, что количество возвращенных записей, так как записи могут охватывать несколько строк.

Объекты DictReader имеют следующий публичный атрибут:

csvreader.fieldnames

Если не передан в качестве параметра при создании объекта, этот атрибут инициализируется при первом доступе или при чтении первой записи из файла.

Объекты писателя

Объекты Writer (экземпляры DictWriter и объекты, возвращаемые функцией writer()) имеют следующие публичные методы. Строка row должна быть итерабельной строкой или числом для объектов Writer и словарем, отображающим имена полей на строки или числа (пропуская их сначала через str()) для объектов DictWriter. Обратите внимание, что комплексные числа записываются в окружении паренсов. Это может вызвать некоторые проблемы для других программ, читающих файлы CSV (если они вообще поддерживают комплексные числа).

csvwriter.writerow(row)

Записывает параметр row в файловый объект писателя, отформатированный в соответствии с текущим Dialect. Возвращает возвращаемое значение вызова метода write базового файлового объекта.

Изменено в версии 3.5: Добавлена поддержка произвольных итераций.

csvwriter.writerows(rows)

Записать все элементы в rows (итерабельность объектов row, как описано выше) в объект файла писателя, отформатированный в соответствии с текущим диалектом.

Объекты Writer имеют следующий публичный атрибут:

csvwriter.dialect

Описание диалекта, используемого писателем, доступное только для чтения.

Объекты DictWriter имеют следующий публичный метод:

DictWriter.writeheader()

Записать строку с именами полей (как указано в конструкторе) в файловый объект писателя, отформатированную в соответствии с текущим диалектом. Возвращает возвращаемое значение вызова csvwriter.writerow(), используемого внутри.

Добавлено в версии 3.2.

Изменено в версии 3.8: writeheader() теперь также возвращает значение, возвращаемое методом csvwriter.writerow(), который он использует внутри.

Примеры

Простейший пример чтения файла CSV:

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

Чтение файла с альтернативным форматом:

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

Соответствующий простейший пример написания:

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

Поскольку open() используется для открытия файла CSV для чтения, файл по умолчанию будет декодирован в юникод с использованием системной кодировки по умолчанию (см. locale.getpreferredencoding()). Чтобы декодировать файл в другой кодировке, используйте аргумент encoding в open:

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

То же самое относится и к записи в кодировке, отличной от системной кодировки по умолчанию: укажите аргумент кодировки при открытии выходного файла.

Регистрация нового диалекта:

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

Несколько более продвинутое использование ридера — отлавливание и сообщение об ошибках:

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

И хотя модуль не поддерживает непосредственно разбор строк, это можно легко сделать:

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

Сноски

1(1,2)

Если newline='' не указано, новые строки, встроенные в поля с кавычками, будут интерпретированы неправильно, а на платформах, использующих \r\n переносы строк при записи, будет добавлено дополнительное \r. Всегда безопасно указывать newline='', поскольку модуль csv выполняет собственную (universal) обработку новых строк.

Вернуться на верх