Литмир - Электронная Библиотека
A
A

Формат 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() и объектов, которые они порождают.

Пакет email

Модули пакета email помогут разобрать, изменить и сгенерировать сообщение в формате RFC 2822. Наиболее часто RFC 2822 применяется в сообщениях электронной почты в Интернете.

В пакете есть несколько модулей, назначение которых (кратко) указано ниже:

Листинг

Message

Модуль определяет класс Message — основной класс для представления сообщения в пакете email.

Листинг

Parser

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

Листинг

Header

Модуль для работы с полями, в которых используется кодировка, отличная от ASCII.

Листинг

Generator

Порождает текст сообщения RFC 2822 на основании объектной модели.

Листинг

Utils

Различные утилиты, которые решают разнообразные небольшие задачи, связанные с сообщениями.

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

Разбор сообщения. Класс Message

Класс Message — центральный во всем пакете email. Он определяет методы для работы с сообщением, которое состоит из заголовка (header) и тела (payload). Поле заголовка имеет название и значение, разделенное двоеточием (двоеточие не входит ни в название, ни в значение). Названия полей нечувствительны к регистру букв при поиске значения, хотя хранятся с учетом регистра. В классе также определены методы для доступа к некоторым часто используемым сведениям (кодировке сообщения, типу содержимого и т.п.).

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

Пример наиболее употребительных методов экземпляров класса Message с пояснениями:

Листинг

>>> import email

>>> input_file = open(«pr1.eml»)

>>> msg = email.message_from_file(input_file)

Здесь используется функция email.message_from_file() для чтения сообщения из файла pr1.eml. Сообщение можно получить и из строки с помощью функции email.message_from_string(). А теперь следует произвести некоторые операции над этим сообщением (не стоит обращать внимания на странные имена — сообщение было взято из папки СПАМ). Доступ к полям по имени осуществляется так:

Листинг

>>> print msg['from']

«felton olive» <[email protected]>

>>> msg.get_all('received')

['from mail.onego.ru\n\tby localhost with POP3 (fetchmail–6.2.5

polling mail.onego.ru account spam)\n\tfor spam@localhost

(single–drop); Wed, 01 Sep 2004 15:46:33 +0400 (MSD)',

'from thecanadianteacher.com ([222.65.104.100])\n\tby mail.onego.ru

31
{"b":"429288","o":1}