Язык программирования Python

Формат CSV


Файл в формате CSV (comma-separated values - значения, разделенные запятыми) - универсальное средство для переноса табличной информации между приложениями (электронными таблицами, СУБД, адресными книгами и т.п.). К сожалению, формат файла не имеет строго определенного стандарта, поэтому между файлами, порождаемыми различными приложениями, существуют некоторые тонкие различия. Внутри файл выглядит примерно так (файл pr.csv):

name,number,text a,1,something here b,2,"one, two, three" c,3,"no commas here"

Для работы с CSV-файлами имеются две основные функции:

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

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

writer(csvfile[, dialect='excel'[, fmtparam]])

Возвращает пишущий объект для записи пользовательских данных с использованием разделителя в заданный файлоподобный объект. Параметры dialect и fmtparam имеют тот же смысл, что и выше. Все данные, кроме строк, обрабатывают функцией str() перед помещением в файл.

В следующем примере читается CSV-файл и записывается другой, где числа второго столбца увеличены на единицу:

import csv input_file = open("pr.csv", "rb") rdr = csv.reader(input_file) output_file = open("pr1.csv", "wb") wrtr = csv.writer(output_file) for rec in rdr: try: rec[1] = int(rec[1]) + 1 except: pass wrtr.writerow(rec) input_file.close() output_file.close()


В результате получится файл pr1.csv следующего содержания:

name,number,text a,2,something here b,3,"one, two, three" c,4,no commas here

Модуль также определяет два класса для более удобного чтения и записи значений с использованием словаря. Вызовы конструкторов следующие:

class DictReader(csvfile, fieldnames[, restkey=None[, restval=None[, dialect='excel']]]])

Создает читающий объект, подобный тому, что рассматривался выше, но помещающий считываемые значения в словарь. Параметры csvfile и dialect те же, что и раньше. Параметр fieldnames задает имена полей списком. Параметр restkey задает значение ключа для помещения списка значений, для которых не хватило имен полей. Параметр restval используется как значение в том случае, если в записи не хватает значений для всех полей. Если параметр fieldnames не задан, имена полей будут прочитаны из первой записи CSV-файла. Начиная с Python 2.4, параметр fieldnames необязателен. Если он отсутствует, ключи берутся из первой строки CSV-файла.

class DictWriter(csvfile, fieldnames[, restval=""[, extrasaction='raise'[, dialect='excel']]])

Создает пишущий объект, который записывает в CSV-файл строки, получая данные из словаря. Параметры аналогичны DictReader, но fieldnames обязателен, так как он задает порядок следования полей. Параметр extrasaction указывает на то, какое действие нужно произвести в случае, когда требуемого значения нет в словаре: 'raise' - возбудить исключение ValueError, 'ignore' - игнорировать.

Соответствующий пример дан ниже. В файле pr.csv имена полей заданы в первой строке файла, поэтому можно не задавать fieldnames:

import csv input_file = open("pr.csv", "rb") rdr = csv.DictReader(input_file, fieldnames=['name', 'number', 'text']) output_file = open("pr1.csv", "wb") wrtr = csv.DictWriter(output_file, fieldnames=['name', 'number', 'text']) for rec in rdr: try: rec['number'] = int(rec['number']) + 1 except: pass wrtr.writerow(rec) input_file.close() output_file.close()

Модуль имеет также другие классы и функции, которые можно изучить по документации. На примере этого модуля можно увидеть общий подход к работе с файлом в некотором формате. Следует обратить внимание на следующие моменты:

  • Модули для работы с форматами данных обычно содержат функции или конструкторы классов, в частности Reader и Writer.
  • Эти функции и конструкторы возвращают объекты-итераторы для чтения данных из файла и объекты со специальными методами для записи в файл.
  • Для разных нужд обычно требуется иметь несколько вариантов классов читающих и пишущих объектов. Новые классы могут получаться наследованием от базовых классов либо обертыванием функций, предоставляемых модулем расширения (написанным на C). В приведенном примере DictReader и DictWriter являются обертками для функций reader() и writer() и объектов, которые они порождают.



Содержание раздела