rfc822.md
1> **Источник:** https://python-all.ru/2.7/library/rfc822.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 18.11. [`rfc822`](https://python-all.ru/2.7/library/rfc822.html#module-rfc822) – Разбор заголовков почты RFC 282289Устарело с версии 2.3: Пакет [`email`](https://python-all.ru/2.7/library/email.html#module-email) следует использовать вместо модуля [`rfc822`](https://python-all.ru/2.7/library/rfc822.html#module-rfc822). Этот модуль существует только для поддержки обратной совместимости и удалён в Python 3.1011Этот модуль определяет класс [`Message`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message), который представляет «сообщение электронной почты», как определено в интернет-стандарте [**RFC 2822**](https://python-all.ru/2.7/library/rfc822.html). [1](https://python-all.ru/2.7/library/rfc822.html#id4) Такие сообщения состоят из набора заголовков и тела сообщения. В этом модуле также определён вспомогательный класс [`AddressList`](https://python-all.ru/2.7/library/rfc822.html#rfc822.AddressList) для разбора адресов [**RFC 2822**](https://python-all.ru/2.7/library/rfc822.html). Обратитесь к RFC за информацией о конкретном синтаксисе сообщений [**RFC 2822**](https://python-all.ru/2.7/library/rfc822.html).1213Модуль [`mailbox`](https://python-all.ru/2.7/library/mailbox.html#module-mailbox) предоставляет классы для чтения почтовых ящиков, созданных различными пользовательскими почтовыми программами.1415#### `class rfc822.Message(file[, seekable])`1617Экземпляр [`Message`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message) создаётся с входным объектом в качестве параметра. Message полагается только на то, что входной объект имеет метод [`readline()`](https://python-all.ru/2.7/library/readline.html#module-readline); в частности, подходят обычные файловые объекты. При создании экземпляра заголовки читаются из входного объекта до строки-разделителя (обычно пустой строки) и сохраняются в экземпляре. Тело сообщения, следующее за заголовками, не потребляется.1819Этот класс может работать с любым входным объектом, поддерживающим метод [`readline()`](https://python-all.ru/2.7/library/readline.html#module-readline). Если входной объект имеет возможность seek и tell, будет работать метод [`rewindbody()`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message.rewindbody); кроме того, некорректные строки будут возвращены обратно во входной поток. Если входной объект не имеет seek, но имеет метод `unread()`, который может вернуть строку обратно, [`Message`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message) будет использовать его для возврата некорректных строк. Таким образом, этот класс можно использовать для разбора сообщений, поступающих из буферизованного потока.2021Необязательный аргумент *seekable* предоставляется как обходной путь для некоторых библиотек stdio, в которых `tell()` сбрасывает буферизованные данные, прежде чем обнаружить, что системный вызов `lseek()` не работает. Для максимальной переносимости следует установить аргумент seekable в ноль, чтобы предотвратить этот начальный `tell()` при передаче непозиционируемого объекта, например файлового объекта, созданного из объекта сокета.2223Входные строки, читаемые из файла, могут заканчиваться либо CR-LF, либо одиночным переводом строки; завершающий CR-LF заменяется на одиночный перевод строки перед сохранением строки.2425Все сравнения заголовков выполняются без учёта регистра; например, `m['From']`, `m['from']` и `m['FROM']` дают одинаковый результат.2627#### `class rfc822.AddressList(field)`2829Можно создать экземпляр вспомогательного класса [`AddressList`](https://python-all.ru/2.7/library/rfc822.html#rfc822.AddressList), используя один строковый параметр – список адресов [**RFC 2822**](https://python-all.ru/2.7/library/rfc822.html), разделённых запятыми, для разбора. (Параметр `None` даёт пустой список.)3031#### `rfc822.quote(str)`3233Возвращает новую строку, в которой обратная косая черта в *str* заменена на две обратные косые черты, а двойные кавычки – на обратную косую черту и двойную кавычку.3435#### `rfc822.unquote(str)`3637Возвращает новую строку, которая является *расквотированной* версией *str*. Если *str* начинается и заканчивается двойными кавычками, они удаляются. Аналогично, если *str* начинается и заканчивается угловыми скобками, они удаляются.3839#### `rfc822.parseaddr(address)`4041Разбирает *address*, который должен быть значением какого-либо поля, содержащего адрес, например *To* или *Cc*, на составные части – «имя» и «адрес электронной почты». Возвращает кортеж с этой информацией, если только разбор не завершается ошибкой; в этом случае возвращается кортеж из двух элементов `(None, None)`.4243#### `rfc822.dump_address_pair(pair)`4445Обратная функция к [`parseaddr()`](https://python-all.ru/2.7/library/rfc822.html#rfc822.parseaddr), она принимает кортеж из двух элементов вида `(realname, email_address)` и возвращает строковое значение, подходящее для заголовка *To* или *Cc*. Если первый элемент *pair* равен false, то второй элемент возвращается без изменений.4647#### `rfc822.parsedate(date)`4849Пытается разобрать дату в соответствии с правилами [**RFC 2822**](https://python-all.ru/2.7/library/rfc822.html). Однако некоторые почтовые программы не следуют этому формату, поэтому [`parsedate()`](https://python-all.ru/2.7/library/rfc822.html#rfc822.parsedate) пытается правильно угадать дату в таких случаях. *date* – это строка, содержащая дату в формате [**RFC 2822**](https://python-all.ru/2.7/library/rfc822.html), например, `'Mon, 20 Nov 1995 19:12:08 -0500'`. Если разбор даты успешен, [`parsedate()`](https://python-all.ru/2.7/library/rfc822.html#rfc822.parsedate) возвращает кортеж из 9 элементов, который можно напрямую передать в [`time.mktime()`](https://python-all.ru/2.7/library/time.html#time.mktime); в противном случае возвращается `None`. Обратите внимание, что индексы 6, 7 и 8 кортежа результата не пригодны для использования.5051#### `rfc822.parsedate_tz(date)`5253Выполняет ту же функцию, что и [`parsedate()`](https://python-all.ru/2.7/library/rfc822.html#rfc822.parsedate), но возвращает либо `None`, либо кортеж из 10 элементов; первые 9 элементов образуют кортеж, который можно напрямую передать в [`time.mktime()`](https://python-all.ru/2.7/library/time.html#time.mktime), а десятый – смещение часового пояса даты относительно UTC (официальный термин для среднего времени по Гринвичу). (Обратите внимание, что знак смещения часового пояса противоположен знаку переменной `time.timezone` для того же часового пояса; последняя переменная соответствует стандарту POSIX, тогда как этот модуль следует [**RFC 2822**](https://python-all.ru/2.7/library/rfc822.html).) Если входная строка не содержит часового пояса, последним элементом возвращаемого кортежа является `None`. Обратите внимание, что индексы 6, 7 и 8 результирующего кортежа не могут быть использованы.5455#### `rfc822.mktime_tz(tuple)`5657Преобразует кортеж из 10 элементов, возвращаемый функцией [`parsedate_tz()`](https://python-all.ru/2.7/library/rfc822.html#rfc822.parsedate_tz), во временную метку UTC. Если элемент часового пояса в кортеже равен `None`, предполагается местное время. Небольшой недостаток: сначала первые 8 элементов интерпретируются как местное время, а затем применяется поправка на разницу часовых поясов; это может привести к небольшой ошибке в даты перехода на летнее время. Но для обычного использования это несущественно.5859> **См. также**60>61> **Модуль [`email`](https://python-all.ru/2.7/library/email.html#module-email)**62>63> Комплексный пакет для обработки электронной почты; заменяет модуль [`rfc822`](https://python-all.ru/2.7/library/rfc822.html#module-rfc822).64>65> **Модуль [`mailbox`](https://python-all.ru/2.7/library/mailbox.html#module-mailbox)**66>67> Классы для чтения различных форматов почтовых ящиков, созданных пользовательскими почтовыми программами.68>69> **Модуль [`mimetools`](https://python-all.ru/2.7/library/mimetools.html#module-mimetools)**70>71> Подкласс [`rfc822.Message`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message), обрабатывающий сообщения в кодировке MIME.7273## 18.11.1. Объекты сообщений7475Экземпляр [`Message`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message) имеет следующие методы:7677#### `Message.rewindbody()`7879Перейти к началу тела сообщения. Работает только если файловый объект поддерживает позиционирование.8081#### `Message.isheader(line)`8283Возвращает канонизированное имя поля строки (ключ словаря, который будет использоваться для индексации), если строка является допустимым заголовком [**RFC 2822**](https://python-all.ru/2.7/library/rfc822.html); в противном случае возвращает `None` (что означает, что разбор должен остановиться, а строка должна быть возвращена во входной поток). Иногда бывает полезно переопределить этот метод в подклассе.8485#### `Message.islast(line)`8687Возвращает истину, если данная строка является разделителем, на котором Message должен остановиться. Строка-разделитель потребляется, а позиция чтения файлового объекта устанавливается сразу после неё. По умолчанию этот метод просто проверяет, что строка пуста, но его можно переопределить в подклассе.8889#### `Message.iscomment(line)`9091Возвращает `True`, если данную строку следует полностью игнорировать, просто пропустить. По умолчанию это заглушка, которая всегда возвращает `False`, но вы можете переопределить её в подклассе.9293#### `Message.getallmatchingheaders(name)`9495Возвращает список строк, содержащий все заголовки, соответствующие *name*, если они есть. Каждая физическая строка (строка продолжения или нет) является отдельным элементом списка. Возвращает пустой список, если ни один заголовок не соответствует *name*.9697#### `Message.getfirstmatchingheader(name)`9899Возвращает список строк, включающий первый заголовок, соответствующий *name*, и его строки продолжения (если они есть). Возвращает `None`, если нет заголовка, соответствующего *name*.100101#### `Message.getrawheader(name)`102103Возвращает одну строку, содержащую текст после двоеточия в первом заголовке, соответствующем *name*. Включает начальные пробелы, завершающий символ новой строки, а также внутренние переводы строк и пробелы, если были строки продолжения. Возвращает `None`, если нет заголовка, соответствующего *name*.104105#### `Message.getheader(name[, default])`106107Возвращает одну строку, состоящую из последнего заголовка, соответствующего *name*, но с удалением начальных и конечных пробелов. Внутренние пробелы не удаляются. Необязательный аргумент *default* можно использовать для указания другого значения, возвращаемого при отсутствии заголовка, соответствующего *name*; по умолчанию он равен `None`. Это предпочтительный способ получения разобранных заголовков.108109#### `Message.get(name[, default])`110111Псевдоним для [`getheader()`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message.getheader), чтобы сделать интерфейс более совместимым с обычными словарями.112113#### `Message.getaddr(name)`114115Возвращает пару `(full name, email address)`, разобранную из строки, возвращаемой `getheader(name)`. Если заголовок, соответствующий *name*, отсутствует, возвращает `(None, None)`; в противном случае и полное имя, и адрес являются (возможно, пустыми) строками.116117Пример: если первый заголовок *From* объекта *m* содержит строку `'jack@cwi.nl (Jack Jansen)'`, то `m.getaddr('From')` вернёт пару `('Jack Jansen', 'jack@cwi.nl')`. Если бы заголовок содержал `'Jack Jansen <jack@cwi.nl>'`, результат был бы точно таким же.118119#### `Message.getaddrlist(name)`120121Это похоже на `getaddr(list)`, но разбирает заголовок, содержащий список адресов электронной почты (например, заголовок *To*), и возвращает список пар `(full name, email address)` (даже если в заголовке был только один адрес). Если заголовок, соответствующий *name*, отсутствует, возвращает пустой список.122123Если существует несколько заголовков, соответствующих указанному имени (например, несколько заголовков *Cc*), все они разбираются на адреса. Также разбираются все строки продолжения, содержащиеся в этих заголовках.124125#### `Message.getdate(name)`126127Извлекает заголовок с помощью [`getheader()`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message.getheader) и разбирает его в 9-кортеж, совместимый с [`time.mktime()`](https://python-all.ru/2.7/library/time.html#time.mktime); обратите внимание, что поля 6, 7 и 8 непригодны. Если заголовок, соответствующий *name*, отсутствует или не поддаётся разбору, возвращает `None`.128129Разбор даты – это, похоже, чёрная магия, и не все почтовые программы следуют стандарту. Хотя функция была протестирована и признана корректной на большой коллекции писем из многих источников, всё же возможно, что иногда она будет выдавать неверный результат.130131#### `Message.getdate_tz(name)`132133Извлекает заголовок с помощью [`getheader()`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message.getheader) и разбирает его в 10-кортеж; первые 9 элементов образуют кортеж, совместимый с [`time.mktime()`](https://python-all.ru/2.7/library/time.html#time.mktime), а 10-й – число, указывающее смещение часового пояса даты от UTC. Обратите внимание, что поля 6, 7 и 8 непригодны. Как и в [`getdate()`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message.getdate), если заголовок, соответствующий *name*, отсутствует или не поддаётся разбору, возвращает `None`.134135Экземпляры [`Message`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message) также поддерживают ограниченный интерфейс отображения. В частности: `m[name]` работает как `m.getheader(name)`, но вызывает [`KeyError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.KeyError), если нет соответствующего заголовка; а `len(m)`, `m.get(name[, default])`, `name in m`, `m.keys()`, `m.values()` `m.items()` и `m.setdefault(name[, default])` ведут себя как ожидается, с одной разницей: `setdefault()` использует пустую строку в качестве значения по умолчанию. Экземпляры [`Message`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message) также поддерживают интерфейс записи отображения `m[name] = value` и `del m[name]`. Объекты [`Message`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message) не поддерживают методы `clear()`, [`copy()`](https://python-all.ru/2.7/library/copy.html#module-copy), `popitem()` или `update()` интерфейса отображения. (Поддержка `get()` и `setdefault()` была добавлена только в Python 2.2.)136137Наконец, экземпляры [`Message`](https://python-all.ru/2.7/library/rfc822.html#rfc822.Message) имеют несколько открытых переменных экземпляра:138139#### `Message.headers`140141Список, содержащий весь набор строк заголовков в порядке их чтения (за исключением того, что вызовы setitem могут нарушить этот порядок). Каждая строка содержит завершающий символ новой строки. Пустая строка, завершающая заголовки, в список не включается.142143#### `Message.fp`144145Файл или файлоподобный объект, переданный при создании экземпляра. Может использоваться для чтения содержимого сообщения.146147#### `Message.unixfrom`148149Строка Unix `From`, если она присутствует в сообщении, или пустая строка. Это необходимо для регенерации сообщения в некоторых контекстах, например, в почтовом файле стиля `mbox`.150151## 18.11.2. Объекты AddressList152153Экземпляр [`AddressList`](https://python-all.ru/2.7/library/rfc822.html#rfc822.AddressList) имеет следующие методы:154155#### `AddressList.__len__()`156157Возвращает количество адресов в списке адресов.158159#### `AddressList.__str__()`160161Возвращает каноническое строковое представление списка адресов. Адреса отображаются в форме «имя» \<[host@domain](https://python-all.ru/2.7/library/rfc822.html)\>, разделённые запятыми.162163#### `AddressList.__add__(alist)`164165Возвращает новый экземпляр [`AddressList`](https://python-all.ru/2.7/library/rfc822.html#rfc822.AddressList), содержащий все адреса из обоих операндов [`AddressList`](https://python-all.ru/2.7/library/rfc822.html#rfc822.AddressList), с удалением дубликатов (объединение множеств).166167#### `AddressList.__iadd__(alist)`168169Версия [`__add__()`](https://python-all.ru/2.7/library/rfc822.html#rfc822.AddressList.__add__), изменяющая объект на месте; превращает данный экземпляр [`AddressList`](https://python-all.ru/2.7/library/rfc822.html#rfc822.AddressList) в объединение самого себя и правого экземпляра *alist*.170171#### `AddressList.__sub__(alist)`172173Возвращает новый экземпляр [`AddressList`](https://python-all.ru/2.7/library/rfc822.html#rfc822.AddressList), содержащий все адреса из левого операнда [`AddressList`](https://python-all.ru/2.7/library/rfc822.html#rfc822.AddressList), которые отсутствуют в правом операнде (разность множеств).174175#### `AddressList.__isub__(alist)`176177Версия [`__sub__()`](https://python-all.ru/2.7/library/rfc822.html#rfc822.AddressList.__sub__), изменяющая объект на месте; удаляет из этого списка адреса, которые также присутствуют в *alist*.178179Наконец, экземпляры [`AddressList`](https://python-all.ru/2.7/library/rfc822.html#rfc822.AddressList) имеют одну открытую переменную экземпляра:180181#### `AddressList.addresslist`182183Список кортежей из двух строк, по одному на каждый адрес. В каждом элементе первый – каноническая часть имени, второй – фактический маршрутный адрес (пара «имя пользователя»-«хост.домен», разделённая `'@'`).184185Сноски186187**[1](https://python-all.ru/2.7/library/rfc822.html#id1)**188189Этот модуль изначально соответствовал [**RFC 822**](https://python-all.ru/2.7/library/rfc822.html), отсюда и название. С тех пор [**RFC 2822**](https://python-all.ru/2.7/library/rfc822.html) был выпущен как обновление [**RFC 822**](https://python-all.ru/2.7/library/rfc822.html). Этот модуль следует считать [**RFC 2822**](https://python-all.ru/2.7/library/rfc822.html)-совместимым, особенно в случаях, когда синтаксис или семантика изменились после [**RFC 822**](https://python-all.ru/2.7/library/rfc822.html).190