справочник по Python. мм isbn 9785932861578 9 785932 861578
Скачать 4.21 Mb.
|
w.writerow(row) Записывает в файл единственную запись с данными. Аргумент row должен быть словарем, отображающим имена полей в их значения. w.writerows(rows) Записывает в файл несколько записей данных. Аргумент rows должен быть последовательностью записей, которые можно передать методу writerow(). 684 Глава 24. Обработка и представление данных в Интернете Sniffer() Создает объект класса Sniffer, который используется для автоматического определения формата файла CSV. Экземпляр s класса Sniffer обладает следующими методами: s.sniff(sample [, delimiters]) Просматривает данные, содержащиеся в sample, и возвращает соответству- и возвращает соответству- возвращает соответству- возвращает соответству- соответству- соответству- ющий объект класса Dialect, представляющий формат данных. В аргумен- представляющий формат данных. В аргумен- формат данных. В аргумен- формат данных. В аргумен- данных. В аргумен- данных. В аргумен- . В аргумен- В аргумен- аргумен- аргумен- те sample передается фрагмент файла CSV, содержащий по меньшей мере одну полную запись с данными. В необязательном аргументе delimiters можно передать строку с предполагаемыми символами-разделителями. s.has_header(sample) Просматривает данные, содержащиеся в sample, и возвращает True, если первая запись выглядит, как коллекция с заголовками полей. Диалекты Многие функции и методы в модуле csv имеют специальный параметр, определяющий диалект. Назначение этого параметра состоит в том, чтобы обеспечить возможность настройки под различные разновидности формата CSV (для которого не существует официального «стандарта»), – например, когда значения разделяются запятыми или символами табуляции, когда используются различные соглашения по заключению значений в кавычки и так далее. Новые диалекты определяются как классы, производные от класса Dialect и объявляющие набор атрибутов с теми же именами, что и именованные аргументы функций reader() и writer() (delimiter, doublequote, escapechar, lineterminator , quotechar, quoting, skipinitialspace). Для управления диалектами используются следующие вспомогательные функции: register_dialect(name, dialect) Регистрирует новый объект dialect класса Dialect под именем name. unregister_dialect(name) Удаляет объект класса Dialect с именем name. get_dialect(name) Возвращает объект класса Dialect с именем name. list_dialects() Возвращает список имен зарегистрированных диалектов. В настоящее время существует всего два встроенных диалекта: ‘excel’ и ‘excel-tab’. Пример import csv # Чтение простого файла CSV f = open(“scmods.csv”,”r”) Пакет email 685 for r in csv.reader(f): lastname, firstname, street, city, zip = r print(“{0} {1} {2} {3} {4}”.format(*r)) ёёё # Прочитать с помощью объекта класса DictReader f = open(“address.csv”) r = csv.DictReader(f,[‘lastname’,’firstname’,’street’,’city’,’zip’]) for a in r: print(“{firstname} {lastname} {street} {city} {zip}”.format(**a)) ёёё # Запись простых данных в файл СSV data = [ [‘Blues’,’Elwood’,’1060 W Addison’,’Chicago’,’IL’,’60613’ ], [‘McGurn’,’Jack’,’4802 N Broadway’,’Chicago’,’IL’,’60640’ ], ] f = open(“address.csv”,”w”) w = csv.writer(f) w.writerows(data) f.close() Пакет email Пакет email предоставляет обширный спектр функций и объектов для представления, анализа и управления сообщениями электронной почты, представленными в формате, соответствующем стандарту MIME. Рассматривать в этом разделе все особенности пакета email не имеет особо- го смысла, и это вряд ли представляет интерес для большинства читателей. Поэтому в оставшейся части раздела мы сконцентрируемся на изучении двух основных практических проблем: анализе сообщений электронной почты с целью извлечения полезной информации и создании новых сооб- щений, готовых к отправке средствами модуля smtplib. Анализ сообщений электронной почты На самом верхнем уровне пакет email предоставляет две функции, позво- ляющие выполнять анализ сообщений электронной почты: message_from_file(f) Анализирует сообщение электронной почты, читая его из объекта f, по- хожего на файл, открытого для чтения в текстовом режиме. Исходное со- общение должно быть полноценным сообщением электронной почты в фор- мате MIME, включающем все заголовки, текст и вложения. Возвращает экземпляр класса Message. message_from_string(str) Анализирует сообщение электронной почты, читая его из строки str. Воз- вращает экземпляр класса Message. Экземпляр m класса Message, возвращаемый предыдущими функциями, имитирует словарь и поддерживает следующие операции по поиску дан- ных внутри сообщения: 686 Глава 24. Обработка и представление данных в Интернете Операция Описание m[name] Возвращает значение заголовка с именем name. m.keys() Возвращает список имен всех заголовков в сообщении. m.values() Возвращает список значений всех заголовков в сообщении. m.items() Возвращает список кортежей, содержащих имена и значения заголовков. m.get(name [,def]) Возвращает значение заголовка с именем name . Аргумент def определяет значение по умолчанию, возвращаемое в случае отсутствия искомого заголовка. len( m) Возвращает количество заголовков в сообщении. str( m) Преобразует сообщение в строку. Действует так же, как и метод as_string(). name in m Возвращает True, если в сообщении присутствует заголовок с именем name. В дополнение к этим операциям экземпляр m обладает следующими мето- дами, которые могут использоваться для извлечения информации: m.get_all(name [, default]) Возвращает список всех значений заголовка с именем name. Если искомый заголовок отсутствует, возвращает default. m.get_boundary([default]) Возвращает параметр boundary, найденный в заголовке ‘Content-type’ со- общения. Обычно значением этого параметра является строка, такая как ‘===============0995017162==’ , которая применяется для отделения различ- ных частей сообщения. Если параметр boundary не найден, возвращает default m.get_charset() Возвращает название набора символов, который используется в теле со- общения (например, ‘iso-8859-1’). m.get_charsets([default]) Возвращает список названий всех наборов символов, присутствующих в сообщении. Для сообщений, состоящих из нескольких частей, в список будет включено название кодировки символов для каждой части. Назва- ние набора символов для каждой части извлекается из заголовков ‘Content- type’ , присутствующих в сообщении. Если в какой-либо части название набора символов не указано или отсутствует заголовок ‘Content-type’, для нее возвращается значение аргумента default (по умолчанию принимает значение None). m.get_content_charset([default]) Возвращает название набора символов из первого заголовка ‘Content-type’ в сообщении. Если такой заголовок отсутствует или в нем не указано на- звание набора символов, возвращается значение аргумента default. Пакет email 687 m.get_content_maintype() Возвращает тип основного содержимого (например, ‘text’ или ‘multipart’). m.get_content_subtype() Возвращает подтип содержимого (например, ‘plain’ или ‘mixed’). m.get_content_type() Возвращает строку, содержащую описание типа содержимого сообщения (например, ‘multipart/mixed’ или ‘text/plain’). m.get_default_type() Возвращает тип содержимого по умолчанию (например, ‘text/plain’ для простых сообщений). m.get_filename([default]) Возвращает значение параметра filename из заголовка ‘Content-Disposition’, если имеется. Возвращает значение аргумента default, если заголовок от- сутствует или не содержит параметр filename. m.get_param(param [, default [, header [, unquote]]]) В заголовки сообщений электронной почты часто добавляются дополни- тельные параметры, например параметры ‘charset’ и ‘format’ в заголовке ‘Content-Type: text/plain; charset=”utf-8”; format=flowed’ . Этот метод воз- метод воз- метод воз- воз- воз- вращает значение требуемого параметра заголовка. Аргумент param опреде- ляет имя параметра, аргумент default – значение по умолчанию, возвра- щаемое в случае отсутствия параметра, аргумент header – имя заголовка и аргумент unquote определяет, следует ли убирать кавычки, окружающие параметр. Если аргумент header опущен, по умолчанию используется заго- ловок ‘Content-type’. Аргумент unquote по умолчанию принимает значение True . Возвращаемым значением является либо строка, либо кортеж с тремя элементами (charset, language, value), если параметр представлен в форма- те, соответствующем соглашениям, изложенным в RFC-2231. В последнем случае в поле charset возвращается строка, такая как ‘iso-8859-1’, в поле language – строка с кодом языка, такая как ‘en’, и в поле value – значение параметра. m.get_params([default [, header [, unquote]]]) Возвращает все параметры заголовка header в виде списка. Аргумент de- fault определяет значение, возвращаемое в случае отсутствия заголовка. Если аргумент header опущен, используется заголовок ‘Content-type’. Аргу- мент unquote определяет, следует ли убирать кавычки, окружающие зна- чения параметров (True по умолчанию). Возвращаемый список содержит кортежи вида (name, value), где в поле name содержится имя параметра, а в поле value – значение, возвращаемое методом get_param(). m.get_payload([i [, decode]]) Возвращает содержимое сообщения. Если сообщение имеет простой вид, возвращается строка байтов с телом сообщения. Если сообщение состоит из нескольких частей, возвращается список, включающий все части со- общения. Для сообщений, состоящих из нескольких частей, необязатель- 688 Глава 24. Обработка и представление данных в Интернете ный аргумент i задает индекс в этом списке. Если этот аргумент указан, возвращается только указанный компонент сообщения. Если в аргументе decode передается значение True, содержимое декодируется в соответствии с параметрами заголовка ‘Content-Transfer-Encoding’, который может при- сутствовать в сообщении (например, ‘quoted-printable’, ‘base64’ и так да- лее). Чтобы декодировать содержимое простого сообщения, состоящего из одной части, следует в аргументе i передать значение None, а в аргументе decode – значение True или определить аргумент decode как именованный аргумент. Следует подчеркнуть, что содержимое возвращается как строка байтов с содержимым. Если содержимым является текст в кодировке UTF- 8 или какой-либо другой кодировке, необходимо результат этого метода передать методу decode(), чтобы преобразовать его. m.get_unixfrom() Возвращает строку ‘From ...’ в стиле UNIX, если имеется. m.is_multipart() Возвращает True, если объект m представляет сообщение, состоящее из не- скольких частей. m.walk() Создает генератор, который выполняет итерации по всем частям сообще- ния, каждая из которых также будет представлена экземпляром класса Message . Итерации выполняются сначала в глубину каждой части сообще- ния, а потом происходит переход к следующей части. Обычно эта функция используется для обработки всех компонентов сложных составных сооб- щений. Наконец, экземпляры класса Message обладают несколькими атрибутами, имеющими отношение к низкоуровневым параметрам процесса анализа. m.preamble Любой текст, присутствующий в сообщении, состоящем из нескольких ча- стей, между пустой строкой, обозначающей конец блока заголовков, и пер- вым вхождением строки границы, разделяющей части сообщения и отме- чающей начало первой части сообщения. m.epilogue Любой текст, присутствующий в сообщении, состоящем из нескольких частей, следующий за последним вхождением строки границы в конце со- общения. m.defects Список всех дефектов, обнаруженных при анализе сообщения. Дополни- тельные подробности можно найти в документации к модулю email.errors. Следующий пример иллюстрирует, как можно использовать класс Message для анализа сообщения электронной почты. Данный программный код чи- тает сообщение электронной почты, выводит краткую информацию о заго- ловках, выводит текстовые фрагменты сообщения и сохраняет вложения. Пакет email 689 import email import sys ёёё f = open(sys.argv[1],”r”) # Открыть файл с сообщением m = email.message_from_file(f) # Выполнить анализ ёёё # Вывести информацию об отправителе/получателе print(“From : %s” % m[“from”]) print(“To : %s” % m[“to”]) print(“Subject : %s” % m[“subject”]) print(“”) ёёё if not m.is_multipart(): # Простое сообщение. Просто вывести текст сообщения payload = m.get_payload(decode=True) charset = m.get_content_charset(‘iso-8859-1’) print(payload.decode(charset)) else: # Сообщение состоит из нескольких частей. Обойти все части и # 1. Вывести фрагменты типа text/plain # 2. Сохранить вложения for s in m.walk(): filename = s.get_filename() if filename: print(“Сохранение вложения: %s” % filename) data = s.get_payload(decode=True) open(filename,”wb”).write(data) else: if s.get_content_type() == ‘text/plain’: payload = s.get_payload(decode=True) charset = s.get_content_charset(‘iso-8859-1’) print(payload.decode(charset)) В этом примере важно отметить, что операции, извлекающие содержимое из сообщения, всегда возвращают строки байтов. Если содержимое являет- ся обычным текстом, его следует преобразовать в соответствии с требуемой кодировкой. Такое преобразование в данном примере выполняется с помо- щью вызовов методов m.get_content_charset() и payload.decode(). Составление сообщений электронной почты Чтобы составить новое сообщение электронной почты, необходимо либо создать новый экземпляр класса Message, который определен в модуле email. message , либо использовать экземпляр класса Message, созданный ранее при анализе сообщения (смотрите предыдущий раздел). Message() Создает новое пустое сообщение. Экземпляр m класса Message поддерживает следующие методы, позволяю- щие наполнять сообщение содержимым, добавлять заголовки и другую информацию. 690 Глава 24. Обработка и представление данных в Интернете m.add_header(name, value, **params) Добавляет новый заголовок сообщения. В аргументе name передается имя заголовка, в аргументе value – значение заголовка и в params – набор име- нованных аргументов, представляющих дополнительные необязательные параметры. Например, вызов add_header(‘Foo’,’Bar’,spam=’major’) добавит в сообщение строку заголовка ‘Foo: Bar; spam=”major”’. m.as_string([unixfrom]) Преобразует все сообщение в строку. В аргументе unixfrom передается логи- ческий флаг. Если он имеет значение True, первой строкой сообщения будет строка ‘From ...’ в стиле UNIX. По умолчанию аргумент unixfrom принимает значение False. m.attach(payload) Добавляет вложение в сообщение, состоящее из нескольких частей. В ар- гументе payload должен передаваться другой объект класса Message (на- пример, email.mime.text.MIMEText). За кулисами объект payload добавляется в конец списка, хранящий различные части сообщения. Если сообщение состоит из единственной части, следует использовать метод set_payload(), который записывает простую строку в тело сообщения. m.del_param(param [, header [, requote]]) Удаляет параметр param из заголовка header. Например, если в сообщении присутствует заголовок ‘Foo: Bar; spam=”major”’, вызов del_param(‘spam’,’Foo’) удалит фрагмент ‘spam=”major”’ из заголовка. Если в аргументе requote пере- дается значение True (по умолчанию), все остающиеся значения будут за- ключены в кавычки при перезаписи заголовка. Если опустить аргумент header , действие будет выполнено над заголовком ‘Content-type’. m.replace_header(name, value) Замещает первое вхождение заголовка с именем name значением value. Если искомый заголовок отсутствует, возбуждает исключение KeyError. m.set_boundary(boundary) Устанавливает параметр boundary сообщения в значение boundary. Эта стро- ка добавляется в заголовок ‘Content-type’ сообщения в виде параметра boundary . Если в сообщении отсутствует заголовок ‘Content-type’, возбужда- ет исключение HeaderParseError. m.set_charset(charset) Устанавливает для сообщения кодировку символов по умолчанию. Аргу- мент charset может быть строкой, такой как ‘iso-8859-1’ или ‘euc-jp’. При установке кодировки в заголовок ‘Content-type’ сообщения обычно добав- ляется параметр (например, ‘Content-type: text/html; charset=”iso-8859-1”’). |