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 - API для работы с файлами CSV

Предложение по улучшению Python, в котором предлагалось это дополнение к Python.

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

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

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

Возвращает reader object, который будет обрабатывать строки из заданного csvfile. Файл csv должен представлять собой итерабельную строку, каждая из которых имеет определенный формат csv, заданный программой чтения. Чаще всего csvfile - это файлоподобный объект или список. Если csvfile является файловым объектом, его следует открыть с помощью newline=''. [1] Может быть задан необязательный параметр диалект, который используется для определения набора параметров, характерных для конкретного диалекта 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)

Возвращает объект писателя, отвечающий за преобразование данных пользователя в разделенные строки на заданном файлоподобном объекте. csvfile может быть любым объектом с методом write(). Если csvfile является файловым объектом, он должен быть открыт с помощью newline='' [1]. Может быть задан необязательный параметр диалект, который используется для определения набора параметров, характерных для конкретного диалекта 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, и они будут опущены в результатах. Если указаны fieldnames, то они будут использованы, и первая строка будет включена в результаты. Независимо от того, как определяются имена полей, в словаре сохраняется их исходный порядок.

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

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

Если аргумент, переданный в fieldnames, является итератором, он будет приведен к list.

Изменено в версии 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 не является необязательным.

Если аргумент, переданный в fieldnames, является итератором, он будет приведен к list.

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

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

Added in version 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 заключать в кавычки все нечисловые поля.

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

csv.QUOTE_NONE

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

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

csv.QUOTE_NOTNULL

Указывает объектам writer заключать в кавычки все поля, которые не являются None. Это аналогично QUOTE_ALL, за исключением того, что если значение поля равно None, то записывается пустая (без кавычек) строка.

Указывает объектам reader интерпретировать пустое (без кавычек) поле как None, а в остальном вести себя как QUOTE_ALL.

Added in version 3.12.

csv.QUOTE_STRINGS

Указывает объектам writer всегда помещать кавычки вокруг полей, которые являются строками. Это аналогично QUOTE_NONNUMERIC, за исключением того, что если значение поля равно None, то записывается пустая (без кавычек) строка.

Указывает объектам reader интерпретировать пустую (без кавычек) строку как None, а в остальном вести себя как QUOTE_NONNUMERIC.

Added in version 3.12.

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

exception csv.Error

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

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

Чтобы упростить определение формата входных и выходных записей, специфические параметры форматирования объединяются в диалекты. Диалект - это подкласс класса Dialect, содержащий различные атрибуты, описывающие формат CSV-файла. При создании объектов 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, которое отключает экранирование.

Изменено в версии 3.11: Пустой escapechar не допускается.

Dialect.lineterminator

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

Примечание

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

Dialect.quotechar

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

Изменено в версии 3.11: Пустой символ quotechar не допускается.

Dialect.quoting

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

Dialect.skipinitialspace

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

Dialect.strict

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

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

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

csvreader.__next__()

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

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

csvreader.dialect

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

csvreader.line_num

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

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

DictReader.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(), используемого внутри программы.

Added in version 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.getencoding()). Чтобы декодировать файл в другой кодировке, используйте аргумент encoding в команде open:

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

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

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

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)

Сноски