email.compat32-message.md
1> **Источник:** https://python-all.ru/3.7/library/email.compat32-message.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [`email.message.Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message): представление email-сообщения с помощью API [`compat32`](https://python-all.ru/3.7/library/email.policy.html#email.policy.compat32)89Класс [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message) очень похож на класс [`EmailMessage`](https://python-all.ru/3.7/library/email.message.html#email.message.EmailMessage), но без методов, добавленных в этом классе, и с немного отличающимся поведением по умолчанию некоторых других методов. Здесь также описаны методы, которые, хотя и поддерживаются классом [`EmailMessage`](https://python-all.ru/3.7/library/email.message.html#email.message.EmailMessage), не рекомендуются к использованию, кроме случаев работы с устаревшим кодом.1011В остальном философия и структура обоих классов одинаковы.1213В этом документе описывается поведение при использовании политики [`Compat32`](https://python-all.ru/3.7/library/email.policy.html#email.policy.Compat32) по умолчанию (для [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message)). При использовании другой политики следует использовать класс [`EmailMessage`](https://python-all.ru/3.7/library/email.message.html#email.message.EmailMessage).1415Электронное письмо состоит из *заголовков* и *полезной нагрузки*. Заголовки должны быть [**RFC 5233**](https://python-all.ru/3.7/library/email.compat32-message.html) именами и значениями, где имя поля и значение разделяются двоеточием. Двоеточие не является частью ни имени поля, ни значения поля. Полезная нагрузка может быть простым текстовым сообщением, двоичным объектом или структурированной последовательностью подсообщений, каждое со своим набором заголовков и своей полезной нагрузкой. Последний тип полезной нагрузки обозначается наличием у сообщения MIME-типа, такого как *multipart/\** или *message/rfc822*.1617Концептуальная модель объекта [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message) представляет собой упорядоченный словарь заголовков с дополнительными методами для доступа как к специализированной информации из заголовков, так и к полезной нагрузке, для генерации сериализованной версии сообщения и для рекурсивного обхода дерева объектов. Обратите внимание, что дублирующиеся заголовки поддерживаются, но для доступа к ним необходимо использовать специальные методы.1819Псевдословарь [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message) индексируется по именам заголовков, которые должны быть значениями ASCII. Значения словаря – строки, которые должны содержать только символы ASCII; предусмотрена специальная обработка для входных данных, не являющихся ASCII, но она не всегда дает правильные результаты. Заголовки хранятся и возвращаются с сохранением регистра, но имена полей сопоставляются без учета регистра. Также может присутствовать единичный конвертный заголовок, также известный как заголовок *Unix-From* или заголовок `From_`. *Полезная нагрузка* представляет собой либо строку, либо байты в случае простых объектов сообщений, либо список объектов [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message) для документов-контейнеров MIME (например, *multipart/\** и *message/rfc822*).2021Ниже приведены методы класса [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message):2223#### `class email.message.Message(policy=compat32)`2425Если указан параметр *policy* (он должен быть экземпляром класса [`policy`](https://python-all.ru/3.7/library/email.policy.html#module-email.policy)), используйте заданные им правила для обновления и сериализации представления сообщения. Если *policy* не задан, используется политика [`compat32`](https://python-all.ru/3.7/library/email.policy.html#email.policy.Compat32), которая обеспечивает обратную совместимость с версией Python 3.2 пакета email. Дополнительную информацию см. в документации [`policy`](https://python-all.ru/3.7/library/email.policy.html#module-email.policy).2627Изменено в версии 3.3: Был добавлен именованный аргумент *policy*.2829#### `as_string(unixfrom=False, maxheaderlen=0, policy=None)`3031Возвращает всё сообщение, преобразованное в строку. Если необязательный параметр *unixfrom* имеет значение true, в возвращаемую строку включается конвертный заголовок. Значение *unixfrom* по умолчанию равно `False`. По причинам обратной совместимости *maxheaderlen* по умолчанию равен `0`, поэтому если требуется другое значение, его необходимо указать явно (значение, указанное для *max\_line\_length* в политике, будет проигнорировано этим методом). Аргумент *policy* может быть использован для переопределения политики по умолчанию, полученной из экземпляра сообщения. Это можно использовать для управления некоторыми аспектами форматирования, которое выполняет метод, поскольку указанная *policy* будет передана в `Generator`.3233Преобразование сообщения может вызвать изменения в [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message), если необходимо заполнить значения по умолчанию для завершения преобразования в строку (например, могут быть созданы или изменены MIME-границы).3435Обратите внимание, что этот метод предоставляется для удобства и может не всегда форматировать сообщение так, как вам нужно. Например, по умолчанию он не выполняет преобразование строк, начинающихся с `From`, которое требуется для формата unix mbox. Для большей гибкости создайте экземпляр [`Generator`](https://python-all.ru/3.7/library/email.generator.html#email.generator.Generator) и используйте его метод [`flatten()`](https://python-all.ru/3.7/library/email.generator.html#email.generator.Generator.flatten) напрямую. Например:3637```python38from io import StringIO39from email.generator import Generator40fp = StringIO()41g = Generator(fp, mangle_from_=True, maxheaderlen=60)42g.flatten(msg)43text = fp.getvalue()44```4546Если объект сообщения содержит двоичные данные, которые не закодированы в соответствии со стандартами RFC, несоответствующие данные будут заменены на кодовые точки Unicode «неизвестный символ». (См. также [`as_bytes()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.as_bytes) и [`BytesGenerator`](https://python-all.ru/3.7/library/email.generator.html#email.generator.BytesGenerator).)4748Изменено в версии 3.4: Добавлен именованный аргумент *policy*.4950#### `__str__()`5152Эквивалентно [`as_string()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.as_string). Позволяет `str(msg)` создавать строку, содержащую отформатированное сообщение.5354#### `as_bytes(unixfrom=False, policy=None)`5556Возвращает всё сообщение, преобразованное в объект bytes. Если необязательный параметр *unixfrom* равен true, в возвращаемую строку включается конвертный заголовок. *unixfrom* по умолчанию равен `False`. Аргумент *policy* может использоваться для переопределения политики по умолчанию, полученной из экземпляра сообщения. Это может быть использовано для управления форматированием, создаваемым методом, поскольку указанная *policy* будет передана в `BytesGenerator`.5758Преобразование сообщения может вызвать изменения в [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message), если необходимо заполнить значения по умолчанию для завершения преобразования в строку (например, могут быть созданы или изменены MIME-границы).5960Обратите внимание, что этот метод предоставляется для удобства и может не всегда форматировать сообщение так, как вам нужно. Например, по умолчанию он не выполняет преобразование строк, начинающихся с `From`, которое требуется для формата unix mbox. Для большей гибкости создайте экземпляр [`BytesGenerator`](https://python-all.ru/3.7/library/email.generator.html#email.generator.BytesGenerator) и используйте его метод [`flatten()`](https://python-all.ru/3.7/library/email.generator.html#email.generator.BytesGenerator.flatten) напрямую. Например:6162```python63from io import BytesIO64from email.generator import BytesGenerator65fp = BytesIO()66g = BytesGenerator(fp, mangle_from_=True, maxheaderlen=60)67g.flatten(msg)68text = fp.getvalue()69```7071Новое в версии 3.4.7273#### `__bytes__()`7475Эквивалентно [`as_bytes()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.as_bytes). Позволяет `bytes(msg)` создавать объект bytes, содержащий отформатированное сообщение.7677Новое в версии 3.4.7879#### `is_multipart()`8081Возвращает `True`, если полезная нагрузка сообщения является списком объектов [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message), иначе возвращает `False`. Когда [`is_multipart()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.is_multipart) возвращает `False`, полезная нагрузка должна быть строковым объектом (который может быть двоичной полезной нагрузкой, закодированной с помощью CTE). (Обратите внимание, что возврат `True` методом [`is_multipart()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.is_multipart) не обязательно означает, что «msg.get\_content\_maintype() == 'multipart'» вернёт `True`. Например, `is_multipart` вернёт `True`, когда [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message) имеет тип `message/rfc822`.)8283#### `set_unixfrom(unixfrom)`8485Устанавливает конвертный заголовок сообщения равным *unixfrom*, который должен быть строкой.8687#### `get_unixfrom()`8889Возвращает конвертный заголовок сообщения. По умолчанию равен `None`, если конвертный заголовок никогда не был установлен.9091#### `attach(payload)`9293Добавляет указанный *payload* к текущему payload, который до вызова должен быть `None` или списком объектов [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message). После вызова payload всегда будет списком объектов [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message). Если нужно установить payload в виде скалярного объекта (например, строки), используйте [`set_payload()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.set_payload).9495Это устаревший метод. В классе `EmailMessage` его функциональность заменена методами [`set_content()`](https://python-all.ru/3.7/library/email.message.html#email.message.EmailMessage.set_content), `make` и `add`.9697#### `get_payload(i=None, decode=False)`9899Возвращает текущий payload: список объектов [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message), если [`is_multipart()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.is_multipart) равно `True`, или строку, если [`is_multipart()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.is_multipart) равно `False`. Если payload является списком и вы изменяете его, вы изменяете payload сообщения на месте.100101С необязательным аргументом *i*, [`get_payload()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.get_payload) возвращает *i*-й элемент payload (нумерация с нуля), если [`is_multipart()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.is_multipart) равно `True`. Возникает [`IndexError`](https://python-all.ru/3.7/library/exceptions.html#IndexError), если *i* меньше 0 или больше или равно количеству элементов в payload. Если payload является строкой (т.е. [`is_multipart()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.is_multipart) равно `False`) и передан *i*, возникает [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError).102103Необязательный флаг *decode* указывает, нужно ли декодировать payload в соответствии с заголовком *Content-Transfer-Encoding*. Когда `True` и сообщение не является multipart, payload будет декодирован, если значение этого заголовка равно `quoted-printable` или `base64`. Если используется другая кодировка или заголовок *Content-Transfer-Encoding* отсутствует, payload возвращается как есть (без декодирования). Во всех случаях возвращаемые данные являются бинарными. Если сообщение multipart и флаг *decode* равен `True`, возвращается `None`. Если payload в формате base64 был сформирован некорректно (отсутствует дополнение, символы вне алфавита base64), в свойство defect сообщения добавляется соответствующий дефект (`InvalidBase64PaddingDefect` или `InvalidBase64CharactersDefect` соответственно).104105Когда *decode* равен `False` (по умолчанию), тело возвращается в виде строки без декодирования *Content-Transfer-Encoding*. Однако для *Content-Transfer-Encoding* со значением 8bit предпринимается попытка декодировать исходные байты с использованием `charset`, указанной в заголовке *Content-Type*, с помощью обработчика ошибок `replace`. Если `charset` не указана или указанная `charset` не распознана пакетом email, тело декодируется с использованием кодировки ASCII по умолчанию.106107Это устаревший метод. В классе `EmailMessage` его функциональность заменена методами [`get_content()`](https://python-all.ru/3.7/library/email.message.html#email.message.EmailMessage.get_content) и [`iter_parts()`](https://python-all.ru/3.7/library/email.message.html#email.message.EmailMessage.iter_parts).108109#### `set_payload(payload, charset=None)`110111Устанавливает payload всего объекта сообщения в *payload*. Ответственность за соблюдение инвариантов payload лежит на клиенте. Необязательный *charset* задаёт кодировку сообщения по умолчанию; подробнее см. [`set_charset()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.set_charset).112113Это устаревший метод. В классе `EmailMessage` его функциональность заменена методом [`set_content()`](https://python-all.ru/3.7/library/email.message.html#email.message.EmailMessage.set_content).114115#### `set_charset(charset)`116117Устанавливает кодировку payload в *charset*, который может быть экземпляром [`Charset`](https://python-all.ru/3.7/library/email.charset.html#email.charset.Charset) (см. [`email.charset`](https://python-all.ru/3.7/library/email.charset.html#module-email.charset)), строкой с названием кодировки или `None`. Если это строка, она преобразуется в экземпляр [`Charset`](https://python-all.ru/3.7/library/email.charset.html#email.charset.Charset). Если *charset* равен `None`, параметр `charset` удаляется из заголовка *Content-Type* (сообщение больше не изменяется). Любое другое значение вызывает [`TypeError`](https://python-all.ru/3.7/library/exceptions.html#TypeError).118119Если отсутствует заголовок *MIME-Version*, он будет добавлен. Если отсутствует заголовок *Content-Type*, он будет добавлен со значением *text/plain*. Независимо от того, существует ли заголовок *Content-Type*, его параметр `charset` будет установлен в *charset.output\_charset*. Если *charset.input\_charset* и *charset.output\_charset* различаются, payload будет перекодирован в *output\_charset*. Если отсутствует заголовок *Content-Transfer-Encoding*, payload будет закодирован для передачи при необходимости с использованием указанного [`Charset`](https://python-all.ru/3.7/library/email.charset.html#email.charset.Charset), и будет добавлен соответствующий заголовок. Если заголовок *Content-Transfer-Encoding* уже существует, считается, что payload уже корректно закодирован с использованием этого *Content-Transfer-Encoding*, и он не изменяется.120121Это устаревший метод. В классе `EmailMessage` его функциональность заменена параметром *charset* метода `email.emailmessage.EmailMessage.set_content()`.122123#### `get_charset()`124125Возвращает экземпляр [`Charset`](https://python-all.ru/3.7/library/email.charset.html#email.charset.Charset), связанный с payload сообщения.126127Это устаревший метод. В классе `EmailMessage` он всегда возвращает `None`.128129Следующие методы реализуют интерфейс, похожий на словарь, для доступа к заголовкам сообщения в формате [**RFC 2822**](https://python-all.ru/3.7/library/email.compat32-message.html). Обратите внимание на некоторые семантические отличия от обычного словаря. Например, в словаре нет дублирующихся ключей, а здесь могут быть повторяющиеся заголовки. Также в словарях нет гарантированного порядка ключей, возвращаемых [`keys()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.keys), а в объекте [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message) заголовки всегда возвращаются в том порядке, в котором они встречались в исходном сообщении или были добавлены позже. Любой удалённый и затем повторно добавленный заголовок всегда добавляется в конец списка заголовков.130131Эти семантические различия являются намеренными и направлены на максимальное удобство.132133Обратите внимание, что во всех случаях заголовки конверта, присутствующие в сообщении, не включаются в интерфейс отображения.134135В модели, созданной из байтов, любые значения заголовков, которые (вопреки RFC) содержат не-ASCII байты, при получении через этот интерфейс будут представлены как объекты [`Header`](https://python-all.ru/3.7/library/email.header.html#email.header.Header) с кодировкой *unknown-8bit*.136137#### `__len__()`138139Возвращает общее количество заголовков, включая дубликаты.140141#### `__contains__(name)`142143Возвращает `True`, если объект сообщения содержит поле с именем *name*. Сравнение выполняется без учёта регистра, и *name* не должен включать завершающее двоеточие. Используется для оператора `in`, например:144145```python146if 'message-id' in myMessage:147 print('Message-ID:', myMessage['message-id'])148```149150#### `__getitem__(name)`151152Возвращает значение указанного поля заголовка. *name* не должен содержать разделитель-двоеточие. Если заголовок отсутствует, возвращается `None`; исключение [`KeyError`](https://python-all.ru/3.7/library/exceptions.html#KeyError) никогда не возбуждается.153154Обратите внимание: если указанное поле встречается в заголовках сообщения более одного раза, то не определено, какое именно из этих значений будет возвращено. Используйте метод [`get_all()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.get_all), чтобы получить значения всех существующих заголовков с данным именем.155156#### `__setitem__(name, val)`157158Добавляет заголовок в сообщение с именем поля *name* и значением *val*. Поле добавляется в конец существующих полей сообщения.159160Обратите внимание, что это *не* перезаписывает и не удаляет существующие заголовки с тем же именем. Если требуется гарантировать, что новый заголовок будет единственным в сообщении с именем поля *name*, сначала удалите это поле, например:161162```python163del msg['subject']164msg['subject'] = 'Python roolz!'165```166167#### `__delitem__(name)`168169Удаляет все вхождения поля с именем *name* из заголовков сообщения. Исключение не возбуждается, если указанное поле отсутствует в заголовках.170171#### `keys()`172173Возвращает список всех имён полей заголовков сообщения.174175#### `values()`176177Возвращает список всех значений полей сообщения.178179#### `items()`180181Возвращает список кортежей из двух элементов, содержащих все заголовки и значения полей сообщения.182183#### `get(name, failobj=None)`184185Возвращает значение указанного поля заголовка. Этот метод идентичен методу [`__getitem__()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.__getitem__) за исключением того, что если указанный заголовок отсутствует, возвращается необязательный параметр *failobj* (по умолчанию `None`).186187Вот несколько дополнительных полезных методов:188189#### `get_all(name, failobj=None)`190191Возвращает список всех значений для поля с именем *name*. Если в сообщении нет таких заголовков, возвращается *failobj* (по умолчанию `None`).192193#### `add_header(_name, _value, **_params)`194195Расширенная настройка заголовка. Этот метод похож на [`__setitem__()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.__setitem__), за исключением того, что дополнительные параметры заголовка можно передавать в виде именованных аргументов. *\_name* – это добавляемое поле заголовка, а *\_value* – *основное* значение заголовка.196197Для каждого элемента в словаре именованных аргументов *\_params* ключ воспринимается как имя параметра, при этом символы подчеркивания заменяются на дефисы (поскольку дефисы недопустимы в идентификаторах Python). Обычно параметр добавляется как `key="value"`, если только значение не равно `None`, в этом случае будет добавлен только ключ. Если значение содержит не-ASCII символы, его можно указать в виде кортежа из трех элементов в формате `(CHARSET, LANGUAGE, VALUE)`, где `CHARSET` – строка, задающая кодировку для кодирования значения, `LANGUAGE` обычно может быть установлен в `None` или пустую строку (см. [**RFC 2231**](https://python-all.ru/3.7/library/email.compat32-message.html) для других возможностей), а `VALUE` – строковое значение, содержащее не-ASCII кодовые точки. Если кортеж из трех элементов не передан и значение содержит не-ASCII символы, оно автоматически кодируется в формат [**RFC 2231**](https://python-all.ru/3.7/library/email.compat32-message.html) с использованием `CHARSET` равного `utf-8` и `LANGUAGE` равного `None`.198199Вот пример:200201```python202msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')203```204205Это добавит заголовок, который выглядит как206207```python208Content-Disposition: attachment; filename="bud.gif"209```210211Пример с не-ASCII символами:212213```python214msg.add_header('Content-Disposition', 'attachment',215 filename=('iso-8859-1', '', 'Fußballer.ppt'))216```217218Что даёт219220```python221Content-Disposition: attachment; filename*="iso-8859-1''Fu%DFballer.ppt"222```223224#### `replace_header(_name, _value)`225226Заменяет заголовок. Заменяет первый заголовок в сообщении, который совпадает с *\_name*, сохраняя порядок заголовков и регистр имени поля. Если подходящий заголовок не найден, возбуждается [`KeyError`](https://python-all.ru/3.7/library/exceptions.html#KeyError).227228#### `get_content_type()`229230Возвращает тип содержимого сообщения. Возвращаемая строка приводится к нижнему регистру в форме *maintype/subtype*. Если в сообщении не было заголовка *Content-Type*, будет возвращен тип по умолчанию, заданный [`get_default_type()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.get_default_type). Поскольку согласно [**RFC 2045**](https://python-all.ru/3.7/library/email.compat32-message.html) сообщения всегда имеют тип по умолчанию, [`get_content_type()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.get_content_type) всегда возвращает значение.231232[**RFC 2045**](https://python-all.ru/3.7/library/email.compat32-message.html) определяет тип по умолчанию сообщения как *text/plain*, если только оно не находится внутри контейнера *multipart/digest*, в этом случае он будет *message/rfc822*. Если заголовок *Content-Type* содержит недопустимую спецификацию типа, [**RFC 2045**](https://python-all.ru/3.7/library/email.compat32-message.html) предписывает, что типом по умолчанию должен быть *text/plain*.233234#### `get_content_maintype()`235236Возвращает основной тип содержимого сообщения. Это часть *maintype* строки, возвращаемой [`get_content_type()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.get_content_type).237238#### `get_content_subtype()`239240Возвращает подтип содержимого сообщения. Это часть *subtype* строки, возвращаемой [`get_content_type()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.get_content_type).241242#### `get_default_type()`243244Возвращает тип содержимого по умолчанию. Большинство сообщений имеют тип содержимого по умолчанию *text/plain*, за исключением сообщений, которые являются подчастями контейнеров *multipart/digest*. Такие подчасти имеют тип содержимого по умолчанию *message/rfc822*.245246#### `set_default_type(ctype)`247248Устанавливает тип содержимого по умолчанию. *ctype* должен быть либо *text/plain*, либо *message/rfc822*, хотя это не принудительно. Тип содержимого по умолчанию не хранится в заголовке *Content-Type*.249250#### `get_params(failobj=None, header='content-type', unquote=True)`251252Возвращает параметры заголовка *Content-Type* сообщения в виде списка. Элементы возвращаемого списка – кортежи из двух элементов (ключ/значение), разделённые знаком `'='`. Левая часть от `'='` – ключ, а правая – значение. Если в параметре нет знака `'='`, значением является пустая строка; в противном случае значение соответствует [`get_param()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.get_param) и не экранируется, если необязательный параметр *unquote* равен `True` (по умолчанию).253254Необязательный параметр *failobj* – объект, возвращаемый при отсутствии заголовка *Content-Type*. Необязательный параметр *header* – заголовок, который нужно искать вместо *Content-Type*.255256Это устаревший метод. В классе `EmailMessage` его функциональность заменена свойством *params* отдельных объектов заголовков, возвращаемых методами доступа к заголовкам.257258#### `get_param(param, failobj=None, header='content-type', unquote=True)`259260Возвращает значение параметра *param* заголовка *Content-Type* в виде строки. Если сообщение не содержит заголовка *Content-Type* или такого параметра нет, возвращается *failobj* (по умолчанию `None`).261262Необязательный параметр *header*, если указан, задаёт заголовок сообщения, который следует использовать вместо *Content-Type*.263264Ключи параметров всегда сравниваются без учёта регистра. Возвращаемое значение может быть строкой или кортежем из трёх элементов, если параметр был закодирован по [**RFC 2231**](https://python-all.ru/3.7/library/email.compat32-message.html). Если это кортеж из трёх элементов, элементы значения имеют вид `(CHARSET, LANGUAGE, VALUE)`. Обратите внимание, что и `CHARSET`, и `LANGUAGE` могут быть `None`; в этом случае следует считать, что `VALUE` закодирован в кодировке `us-ascii`. Обычно `LANGUAGE` можно игнорировать.265266Если вашему приложению безразлично, был ли параметр закодирован по [**RFC 2231**](https://python-all.ru/3.7/library/email.compat32-message.html), можно свернуть значение параметра, вызвав [`email.utils.collapse_rfc2231_value()`](https://python-all.ru/3.7/library/email.utils.html#email.utils.collapse_rfc2231_value) и передав возвращаемое значение из [`get_param()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.get_param). Это вернёт подходящим образом декодированную строку Unicode, если значение является кортежем, или исходную строку без кавычек, если нет. Например:267268```python269rawparam = msg.get_param('foo')270param = email.utils.collapse_rfc2231_value(rawparam)271```272273В любом случае значение параметра (возвращённая строка или элемент `VALUE` кортежа из трёх элементов) всегда не экранируется, если только *unquote* не установлен в `False`.274275Это устаревший метод. В классе `EmailMessage` его функциональность заменена свойством *params* отдельных объектов заголовков, возвращаемых методами доступа к заголовкам.276277#### `set_param(param, value, header='Content-Type', requote=True, charset=None, language='', replace=False)`278279Устанавливает параметр в заголовке *Content-Type*. Если параметр уже существует в заголовке, его значение будет заменено на *value*. Если заголовок *Content-Type* ещё не задан для этого сообщения, он будет установлен в *text/plain*, а новое значение параметра будет добавлено в соответствии с [**RFC 2045**](https://python-all.ru/3.7/library/email.compat32-message.html).280281Необязательный параметр *header* задаёт альтернативный заголовок для *Content-Type*; все параметры будут экранированы при необходимости, если только необязательный параметр *requote* не равен `False` (по умолчанию `True`).282283Если указан необязательный параметр *charset*, параметр будет закодирован в соответствии с [**RFC 2231**](https://python-all.ru/3.7/library/email.compat32-message.html). Необязательный параметр *language* задаёт язык по RFC 2231, по умолчанию – пустая строка. И *charset*, и *language* должны быть строками.284285Если *replace* равен `False` (по умолчанию), заголовок перемещается в конец списка заголовков. Если *replace* равен `True`, заголовок будет обновлён на месте.286287Изменено в версии 3.4: `replace` добавлен ключевой параметр.288289#### `del_param(param, header='content-type', requote=True)`290291Полностью удаляет указанный параметр из заголовка *Content-Type*. Заголовок будет перезаписан на месте без параметра и его значения. Все значения будут экранированы при необходимости, если только *requote* не равен `False` (по умолчанию `True`). Необязательный параметр *header* задаёт альтернативу заголовку *Content-Type*.292293#### `set_type(type, header='Content-Type', requote=True)`294295Устанавливает основной тип и подтип для заголовка *Content-Type*. *type* должен быть строкой вида *maintype/subtype*, в противном случае возбуждается [`ValueError`](https://python-all.ru/3.7/library/exceptions.html#ValueError).296297Этот метод заменяет заголовок *Content-Type*, сохраняя все параметры на месте. Если *requote* равен `False`, экранирование существующего заголовка остаётся без изменений; в противном случае параметры будут экранированы (по умолчанию).298299Альтернативный заголовок можно указать в аргументе *header*. При установке заголовка *Content-Type* также добавляется заголовок *MIME-Version*.300301Это устаревший метод. В классе `EmailMessage` его функциональность заменена методами `make_` и `add_`.302303#### `get_filename(failobj=None)`304305Возвращает значение параметра `filename` заголовка *Content-Disposition* сообщения. Если в заголовке нет параметра `filename`, этот метод пытается найти параметр `name` в заголовке *Content-Type*. Если ни один из них не найден или заголовок отсутствует, возвращается *failobj*. Возвращаемая строка всегда будет раскрыта в соответствии с [`email.utils.unquote()`](https://python-all.ru/3.7/library/email.utils.html#email.utils.unquote).306307#### `get_boundary(failobj=None)`308309Возвращает значение параметра `boundary` заголовка *Content-Type* сообщения или *failobj*, если заголовок отсутствует или не содержит параметра `boundary`. Возвращаемая строка всегда будет раскрыта в соответствии с [`email.utils.unquote()`](https://python-all.ru/3.7/library/email.utils.html#email.utils.unquote).310311#### `set_boundary(boundary)`312313Устанавливает параметр `boundary` заголовка *Content-Type* в значение *boundary*. [`set_boundary()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.set_boundary) всегда будет заключать *boundary* в кавычки при необходимости. Возбуждается исключение [`HeaderParseError`](https://python-all.ru/3.7/library/email.errors.html#email.errors.HeaderParseError), если объект сообщения не имеет заголовка *Content-Type*.314315Обратите внимание, что использование этого метода незначительно отличается от удаления старого заголовка *Content-Type* и добавления нового с новым boundary через [`add_header()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.add_header), поскольку [`set_boundary()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.set_boundary) сохраняет порядок заголовка *Content-Type* в списке заголовков. Однако он *не* сохраняет строки продолжения, которые могли быть в исходном заголовке *Content-Type*.316317#### `get_content_charset(failobj=None)`318319Возвращает параметр `charset` заголовка *Content-Type*, приведённый к нижнему регистру. Если заголовок *Content-Type* отсутствует или не содержит параметра `charset`, возвращается *failobj*.320321Обратите внимание, что этот метод отличается от [`get_charset()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.get_charset), который возвращает экземпляр [`Charset`](https://python-all.ru/3.7/library/email.charset.html#email.charset.Charset) для кодировки тела сообщения по умолчанию.322323#### `get_charsets(failobj=None)`324325Возвращает список, содержащий имена наборов символов в сообщении. Если сообщение является *multipart*, список будет содержать по одному элементу для каждой вложенной части в полезной нагрузке; в противном случае это будет список длиной 1.326327Каждый элемент списка будет строкой, которая является значением параметра `charset` в заголовке *Content-Type* для представленной вложенной части. Однако если у вложенной части нет заголовка *Content-Type*, нет параметра `charset`, или она не относится к основному MIME-типу *text*, то такой элемент списка будет равен *failobj*.328329#### `get_content_disposition()`330331Возвращает значение заголовка *Content-Disposition* сообщения в нижнем регистре (без параметров), если он есть, или `None`. Возможные значения этого метода: *inline*, *attachment* или `None`, если сообщение соответствует [**RFC 2183**](https://python-all.ru/3.7/library/email.compat32-message.html).332333Новое в версии 3.5.334335#### `walk()`336337Метод [`walk()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.walk) – это универсальный генератор, который можно использовать для обхода всех частей и подчастей дерева объекта сообщения в порядке прямого обхода в глубину. Обычно [`walk()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.walk) используется как итератор в цикле `for`; каждая итерация возвращает следующую подчасть.338339Вот пример, который выводит MIME-тип каждой части многокомпонентной структуры сообщения:340341```pycon342>>> for part in msg.walk():343... print(part.get_content_type())344multipart/report345text/plain346message/delivery-status347text/plain348text/plain349message/rfc822350text/plain351```352353`walk` обходит подчасти любой части, для которой [`is_multipart()`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message.is_multipart) возвращает `True`, даже если `msg.get_content_maintype() == 'multipart'` может возвращать `False`. Это видно в нашем примере при использовании отладочной вспомогательной функции `_structure`:354355```pycon356>>> for part in msg.walk():357... print(part.get_content_maintype() == 'multipart',358... part.is_multipart())359True True360False False361False True362False False363False False364False True365False False366>>> _structure(msg)367multipart/report368 text/plain369 message/delivery-status370 text/plain371 text/plain372 message/rfc822373 text/plain374```375376Здесь части `message` не являются `multiparts`, но содержат подчасти. `is_multipart()` возвращает `True`, а `walk` спускается в подчасти.377378Объекты [`Message`](https://python-all.ru/3.7/library/email.compat32-message.html#email.message.Message) также могут опционально содержать два атрибута экземпляра, которые можно использовать при создании обычного текста MIME-сообщения.379380#### `preamble`381382Формат MIME-документа допускает наличие некоторого текста между пустой строкой после заголовков и первой строкой границы multipart. Обычно этот текст не виден в MIME-совместимом почтовом клиенте, поскольку он находится вне стандартной MIME-защиты. Однако при просмотре необработанного текста сообщения или при просмотре сообщения в клиенте, не поддерживающем MIME, этот текст может стать видимым.383384Атрибут *preamble* содержит этот дополнительный текст за пределами MIME-защиты для MIME-документов. Когда [`Parser`](https://python-all.ru/3.7/library/email.parser.html#email.parser.Parser) обнаруживает некоторый текст после заголовков, но до первой строки границы, он присваивает этот текст атрибуту *preamble* сообщения. Когда [`Generator`](https://python-all.ru/3.7/library/email.generator.html#email.generator.Generator) записывает текстовое представление MIME-сообщения и обнаруживает, что сообщение имеет атрибут *preamble*, он записывает этот текст в области между заголовками и первой границей. Подробнее см. [`email.parser`](https://python-all.ru/3.7/library/email.parser.html#module-email.parser) и [`email.generator`](https://python-all.ru/3.7/library/email.generator.html#module-email.generator).385386Обратите внимание: если у объекта сообщения нет преамбулы, атрибут *preamble* будет равен `None`.387388#### `epilogue`389390Атрибут *epilogue* действует так же, как атрибут *preamble*, за исключением того, что он содержит текст, который появляется между последней границей и концом сообщения.391392Нет необходимости устанавливать epilogue в пустую строку, чтобы [`Generator`](https://python-all.ru/3.7/library/email.generator.html#email.generator.Generator) выводил символ новой строки в конце файла.393394#### `defects`395396Атрибут *defects* содержит список всех проблем, обнаруженных при разборе этого сообщения. См. [`email.errors`](https://python-all.ru/3.7/library/email.errors.html#module-email.errors) для подробного описания возможных дефектов разбора.397