Документация Python неофициальный перевод
Содержание страницы

csv – чтение и запись CSV-файловcsv – CSV File Reading and Writing

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

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

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

Примечание

Эта версия модуля csv не поддерживает ввод в Юникоде. Кроме того, в настоящее время есть некоторые проблемы с символами ASCII NUL. Поэтому весь ввод должен быть в UTF-8 или в печатном ASCII для безопасности; см. примеры в разделе Примеры. Эти ограничения будут сняты в будущем.

См. также

PEP 305 - API для CSV-файлов
Предложение по улучшению Python, в котором было предложено это дополнение.

Содержимое модуляModule Contents

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

csv.reader(csvfile[, dialect='excel'][, fmtparam])

Возвращает объект чтения, который будет перебирать строки в указанном csvfile. csvfile может быть любым объектом, поддерживающим протокол итератора и возвращающим строку при каждом вызове его метода next() – подходят как файловые объекты, так и списки. Если csvfile является файловым объектом, он должен быть открыт с флагом 'b' на платформах, где это имеет значение. Необязательный параметр dialect может быть задан для определения набора параметров, специфичных для конкретного диалекта CSV. Это может быть экземпляр подкласса класса Dialect или одна из строк, возвращаемых функцией list_dialects(). Другие необязательные именованные аргументы fmtparam могут быть переданы для переопределения отдельных параметров форматирования в текущем диалекте. Полную информацию о диалекте и параметрах форматирования см. в разделе Диалекты и параметры форматирования.

Все считанные данные возвращаются в виде строк. Автоматическое преобразование типов данных не выполняется.

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

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

>>> import csv
>>> spamReader = csv.reader(open('eggs.csv'), 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'][, fmtparam])

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

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

>>> import csv
>>> spamWriter = csv.writer(open('eggs.csv', 'w'), delimiter=' ',
...                         quotechar='|', quoting=QUOTE_MINIMAL)
>>> spamWriter.writerow(['Spam'] * 5 + ['Baked Beans'])
>>> spamWriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])
csv.register_dialect(name[, dialect][, fmtparam])
Связывает dialect с именем name. name должно быть строкой. Диалект может быть указан либо передачей подкласса Dialect, либо через именованные аргументы fmtparam, либо и тем и другим, при этом именованные аргументы переопределяют параметры диалекта. Полную информацию о диалекте и параметрах форматирования см. в разделе Диалекты и параметры форматирования.
csv.unregister_dialect(name)
Удаляет диалект, связанный с name, из реестра диалектов. Исключение Error возбуждается, если name не является зарегистрированным именем диалекта.
csv.get_dialect(name)
Возвращает диалект, связанный с name. Исключение Error возбуждается, если name не является зарегистрированным именем диалекта. Эта функция возвращает неизменяемый Dialect.
csv.list_dialects()
Возвращает имена всех зарегистрированных диалектов.
csv.field_size_limit([new_limit])
Возвращает текущий максимальный размер поля, разрешенный парсером. Если задан new_limit, он становится новым лимитом.

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

class csv.DictReader(csvfile[, fieldnames=None[, restkey=None[, restval=None[, dialect='excel'[, *args, **kwds]]]]])
Create an object which operates like a regular reader but maps the information read into a dict whose keys are given by the optional fieldnames parameter. If the fieldnames parameter is omitted, the values in the first row of the csvfile will be used as the fieldnames. If the row read has fewer fields than the fieldnames sequence, the value of restval will be used as the default value. If the row read has more fields than the fieldnames sequence, the remaining data is added as a sequence keyed by the value of restkey. If the row read has fewer fields than the fieldnames sequence, the remaining keys take the value of the optional restval parameter. Any other optional or keyword arguments are passed to the underlying reader instance.
class csv.DictWriter(csvfile, fieldnames[, restval=''[, extrasaction='raise'[, dialect='excel'[, *args, **kwds]]]])

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

Обратите внимание: в отличие от класса DictReader, параметр fieldnames DictWriter обязателен. Поскольку объекты dict в Python не упорядочены, недостаточно информации, чтобы определить порядок, в котором строка должна быть записана в csvfile.

class csv.Dialect
Класс Dialect – это класс-контейнер, используемый в основном для своих атрибутов, которые определяют параметры для конкретного экземпляра reader или writer.
class csv.excel
Класс excel определяет обычные свойства CSV-файла, созданного Excel. Он зарегистрирован под именем диалекта 'excel'.
class csv.excel_tab
Класс excel_tab определяет обычные свойства файла с разделителями-табуляцией, созданного Excel. Он зарегистрирован под именем диалекта 'excel-tab'.
class csv.Sniffer

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

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

sniff(sample[, delimiters=None])
Анализирует заданный образец sample и возвращает подкласс Dialect, отражающий найденные параметры. Если задан необязательный параметр delimiters, он интерпретируется как строка, содержащая возможные допустимые символы-разделители.
has_header(sample)
Анализирует образец текста (предположительно в формате CSV) и возвращает True, если первая строка выглядит как набор заголовков столбцов.

Пример использования Sniffer:

csvfile = open("example.csv")
dialect = csv.Sniffer().sniff(csvfile.read(1024))
csvfile.seek(0)
reader = csv.reader(csvfile, dialect)
# ... здесь обрабатывается содержимое CSV-файла ...

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

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

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

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

csv.QUOTE_NONE

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

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

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

exception csv.Error
Возбуждается любой из функций при обнаружении ошибки.

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

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

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

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

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

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

Dialect.escapechar
Односимвольная строка, используемая writer для экранирования delimiter, если quoting установлен в QUOTE_NONE, и quotechar, если doublequote равно False. При чтении escapechar удаляет любое специальное значение из следующего символа. По умолчанию None, что отключает экранирование.
Dialect.lineterminator

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

Примечание

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

Dialect.quotechar
Односимвольная строка, используемая для заключения в кавычки полей, содержащих специальные символы, такие как разделитель или quotechar, или содержащих символы новой строки. По умолчанию '"'.
Dialect.quoting
Управляет тем, когда кавычки должны генерироваться писателем и распознаваться читателем. Он может принимать любую из констант QUOTE_* (см. раздел Содержание модуля) и по умолчанию равен QUOTE_MINIMAL.
Dialect.skipinitialspace
Если True, пробелы, непосредственно следующие за разделителем, игнорируются. Значение по умолчанию – False.

Объекты ReaderReader Objects

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

csvreader.next()
Возвращает следующую строку итерируемого объекта reader в виде списка, разобранную в соответствии с текущим диалектом.

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

csvreader.dialect
Доступное только для чтения описание диалекта, используемого синтаксическим анализатором.
csvreader.line_num
Количество строк, прочитанных из итератора-источника. Это число не совпадает с количеством возвращённых записей, так как записи могут занимать несколько строк.

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

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

Объекты WriterWriter Objects

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

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

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

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

ПримерыExamples

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

import csv
reader = csv.reader(open("some.csv", "rb"))
for row in reader:
    print(row)

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

import csv
reader = csv.reader(open("passwd", "rb"), delimiter=':', quoting=csv.QUOTE_NONE)
for row in reader:
    print(row)

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

import csv
writer = csv.writer(open("some.csv", "wb"))
writer.writerows(someiterable)

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

import csv

csv.register_dialect('unixpwd', delimiter=':', quoting=csv.QUOTE_NONE)

reader = csv.reader(open("passwd", "rb"), 'unixpwd')

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

import csv, sys
filename = "some.csv"
reader = csv.reader(open(filename, "rb"))
try:
    for row in reader:
        print(row)
except csv.Error as e:
    sys.exit('file %s, line %d: %s' % (filename, reader.line_num, e))

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

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

Модуль csv напрямую не поддерживает чтение и запись Unicode, но он совместим с 8-битными данными, за исключением некоторых проблем с нулевыми символами ASCII. Поэтому можно написать функции или классы, которые будут обрабатывать кодирование и декодирование, если избегать кодировок, использующих нулевые байты, например UTF-16. Рекомендуется UTF-8.

unicode_csv_reader() ниже – это генератор, который оборачивает csv.reader для обработки данных CSV в Unicode (список строк Unicode). utf_8_encoder() – это генератор, который кодирует строки Unicode в UTF-8, по одной строке (или строке данных) за раз. Закодированные строки разбираются CSV-читателем, и unicode_csv_reader() декодирует ячейки, закодированные в UTF-8, обратно в Unicode:

import csv

def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
    # csv.py не поддерживает Unicode; временно кодируйте как UTF-8:
    csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
                            dialect=dialect, **kwargs)
    for row in csv_reader:
        # декодируйте UTF-8 обратно в Unicode, ячейка за ячейкой:
        yield [unicode(cell, 'utf-8') for cell in row]

def utf_8_encoder(unicode_csv_data):
    for line in unicode_csv_data:
        yield line.encode('utf-8')

Для всех остальных кодировок можно использовать следующие классы: UnicodeReader и UnicodeWriter. Они принимают дополнительный параметр encoding в конструкторе и гарантируют, что данные передаются реальному читателю или писателю в кодировке UTF-8:

import csv, codecs, io

class UTF8Recoder:
    """
    Iterator that reads an encoded stream and reencodes the input to UTF-8
    """
    def __init__(self, f, encoding):
        self.reader = codecs.getreader(encoding)(f)

    def __iter__(self):
        return self

    def __next__(self):
        return next(self.reader).encode("utf-8")

class UnicodeReader:
    """
    A CSV reader which will iterate over lines in the CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        f = UTF8Recoder(f, encoding)
        self.reader = csv.reader(f, dialect=dialect, **kwds)

    def __next__(self):
        row = next(self.reader)
        return [unicode(s, "utf-8") for s in row]

    def __iter__(self):
        return self

class UnicodeWriter:
    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        # Redirect output to a queue
        self.queue = io.StringIO()
        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
        self.stream = f
        self.encoder = codecs.getincrementalencoder(encoding)()

    def writerow(self, row):
        self.writer.writerow([s.encode("utf-8") for s in row])
        # Fetch UTF-8 output from the queue ...
        data = self.queue.getvalue()
        data = data.decode("utf-8")
        # ... and reencode it into the target encoding
        data = self.encoder.encode(data)
        # write to the target stream
        self.stream.write(data)
        # empty queue
        self.queue.truncate(0)

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)