Spec-Zone.ru › Python 2.7

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

Новое в версии 2.3.

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

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

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

Примечание

Эта версия модуля csv не поддерживает ввод Unicode. Также существуют некоторые проблемы с символами ASCII NUL. Поэтому весь ввод должен быть в формате UTF-8 или в печатных ASCII для безопасности; см. примеры в разделе Примеры.

См. также

PEP 305 — API для CSV-файлов

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

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

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

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

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

Каждая строка, считанная из CSV-файла, возвращается как список строк. Автоматическое преобразование типов данных не выполняется.

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

>>> import csv
>>> with open('eggs.csv', 'rb') 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

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

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

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

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

import csv
with open('eggs.csv', 'wb') 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)

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

csv.unregister_dialect(name)

Удаляет диалект, связанный с именем, из реестра диалектов. Возникает исключение Error, если имя не является зарегистрированным именем диалекта.

csv.get_dialect(name)

Возвращает диалект, связанный с именем. Возникает исключение Error, если имя не является зарегистрированным именем диалекта.

Изменено в версии 2.5: Эта функция теперь возвращает неизменяемый Dialect. Раньше возвращался экземпляр запрошенного диалекта. Пользователи могли изменять базовый класс, изменяя поведение активных читателей и писателей.

csv.list_dialects()

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

csv.field_size_limit([new_limit])

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

Новое в версии 2.5.

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

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

Создаёт объект, работающий как обычный читатель, но отображает считанную информацию в словарь, ключами которого являются значения, заданные необязательным параметром fieldnames. Параметр fieldnames — это последовательность элементов, которые соответствуют полям входных данных в порядке. Эти элементы становятся ключами результирующего словаря. Если параметр fieldnames опущен, значения в первой строке файла f будут использованы в качестве имён полей. Если в считанной строке больше полей, чем в последовательности fieldnames, оставшиеся данные добавляются как последовательность, имеющая ключ restkey. Если в считанной строке меньше полей, чем в последовательности fieldnames, оставшиеся ключи принимают значение необязательного параметра restval. Любые другие необязательные или ключевые аргументы передаются в базовую реализацию reader.

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

>>> import csv
>>> with open('names.csv') as csvfile:
...     reader = csv.DictReader(csvfile)
...     for row in reader:
...         print(row['first_name'], row['last_name'])
...
Baked Beans
Lovely Spam
Wonderful Spam
class csv.DictWriter(f, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds)

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

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

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

import csv

with open('names.csv', 'w') 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 — это контейнерный класс, используемый в основном для своих атрибутов, которые используются для определения параметров для конкретного экземпляра 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:

with open('example.csv', 'rb') 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 никогда не цитировать поля. Когда текущий разделитель delimiter встречается в выходных данных, он предваряется текущим символом escapechar. Если escapechar не задан, записыватель генерирует Error, если встречаются символы, требующие экранирования.

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

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

exception csv.Error

Генерируется любыми функциями при обнаружении ошибки.

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

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

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

Dialect.delimiter

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

Dialect.doublequote

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

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

Dialect.escapechar

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

Dialect.lineterminator

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

Примечание

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

Dialect.quotechar

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

Dialect.quoting

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

Dialect.skipinitialspace

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

Dialect.strict

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

3. Объекты-читатели

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

csvreader.next()

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

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

csvreader.dialect

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

csvreader.line_num

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

Введено в версии 2.5.

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

csvreader.fieldnames

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

Изменено в версии 2.6.

4. Объекты записи

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

csvwriter.writerow(row)

Записать параметр строка в файл объекта записи, отформатировав его в соответствии с текущим диалектом.

csvwriter.writerows(rows)

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

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

csvwriter.dialect

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

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

DictWriter.writeheader()

Записать строку с именами полей (как указано в конструкторе).

Введено в версии 2.7.

5. Примеры

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

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

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

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

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

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

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

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

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

import csv, sys
filename = 'some.csv'
with open(filename, 'rb') as f:
    reader = csv.reader(f)
    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 для обработки Unicode данных CSV (список строк 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 doesn't do Unicode; encode temporarily as UTF-8:
    csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
                            dialect=dialect, **kwargs)
    for row in csv_reader:
        # decode UTF-8 back to Unicode, cell by cell:
        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 классы. Они принимают дополнительный параметр кодировка в своем конструкторе и гарантируют, что данные проходят реальный считыватель или записыватель, закодированный как UTF-8:

import csv, codecs, cStringIO

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 self.reader.next().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 = self.reader.next()
        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 = cStringIO.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)

© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/2.7/library/csv.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API