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

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


Так называемый формат CSV (значения, разделенные запятыми) является наиболее распространенным форматом импорта и экспорта для электронных таблиц и баз данных. Формат 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, который будет обрабатывать строки из данного csv-файла. CSV-файл должен представлять собой повторяющийся набор строк, каждая из которых должна быть в определенном читателем формате csv. CSV-файл чаще всего представляет собой файлообразный объект или список. Если 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. Значение Error задается, если name не является зарегистрированным именем диалекта. Эта функция возвращает неизменяемое значение 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)

Создайте объект, который работает как обычный writer, но отображает словари в выходные строки. Параметр 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 определяет обычные свойства CSV-файла, созданного в Excel. Он зарегистрирован с именем на диалекте 'excel'.

class csv.excel_tab

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

class csv.unix_dialect

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

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

class csv.Sniffer

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

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

sniff(sample, delimiters=None)

Проанализируйте данный sample и верните подкласс 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 заключать в кавычки только те поля, которые содержат специальные символы, такие как разделитель, quotechar или любой из символов в lineterminator.

csv.QUOTE_NONNUMERIC

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

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

csv.QUOTE_NONE

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

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

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

exception csv.Error

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

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

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

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

Dialect.delimiter

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

Dialect.doublequote

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

На выходе, если двойная кавычка равна False и escapechar не задан, Error вызывается, если в поле найден quotechar.

Dialect.escapechar

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

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

Dialect.lineterminator

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

Примечание

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

Dialect.quotechar

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

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

Dialect.quoting

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

Dialect.skipinitialspace

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

Dialect.strict

Когда True, вызовите исключение Error при неправильном вводе CSV. Значение по умолчанию False.

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

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

csvreader.__next__()

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

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

csvreader.dialect

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

csvreader.line_num

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

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

DictReader.fieldnames

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

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

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

csvwriter.writerow(row)

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

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

csvwriter.writerows(rows)

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

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

csvwriter.dialect

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

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

DictWriter.writeheader()

Запишите строку с именами полей (как указано в конструкторе) в файловый объект writer, отформатированный в соответствии с текущим диалектом. Верните возвращаемое значение вызова 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-файла для чтения, файл по умолчанию будет декодирован в unicode с использованием системной кодировки по умолчанию (см. 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)

Сноски

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