email.message.md
1> **Источник:** https://python-all.ru/3/library/email.message.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `email.message`: Представление email-сообщения89**Исходный код:** [Lib/email/message.py](https://python-all.ru/src/3.14/Lib/email/message.py)1011---1213Добавлено в версии 3.6: [\[1\]](https://python-all.ru/3/library/email.message.html#id3)1415Центральный класс в пакете [`email`](https://python-all.ru/3/library/email.html#module-email) – это [`EmailMessage`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage) класс, импортируемый из модуля `email.message`. Он является базовым классом для объектной модели `email`. `EmailMessage` предоставляет основные функции для установки и запроса полей заголовков, для доступа к телам сообщений, а также для создания или изменения структурированных сообщений.1617An email message consists of *headers* and a *payload* (which is also referred to as the *content*). Headers are [**RFC 5322**](https://python-all.ru/3/library/email.message.html) or [**RFC 6532**](https://python-all.ru/3/library/email.message.html) style field names and values, where the field name and value are separated by a colon. The colon is not part of either the field name or the field value. The payload may be a simple text message, or a binary object, or a structured sequence of sub-messages each with their own set of headers and their own payload. The latter type of payload is indicated by the message having a MIME type such as *multipart/\** or *message/rfc822*.1819The conceptual model provided by an [`EmailMessage`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage) object is that of an ordered dictionary of headers coupled with a *payload* that represents the [**RFC 5322**](https://python-all.ru/3/library/email.message.html) body of the message, which might be a list of sub-`EmailMessage` objects. In addition to the normal dictionary methods for accessing the header names and values, there are methods for accessing specialized information from the headers (for example the MIME content type), for operating on the payload, for generating a serialized version of the message, and for recursively walking over the object tree.2021Интерфейс, подобный словарю, [`EmailMessage`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage) индексируется по именам заголовков, которые должны быть ASCII-значениями. Значениями словаря являются строки с некоторыми дополнительными методами. Заголовки сохраняются и возвращаются с сохранением регистра, но имена полей сравниваются без учёта регистра. Ключи упорядочены, но, в отличие от настоящего словаря, могут быть дубликаты. Предоставляются дополнительные методы для работы с заголовками, имеющими дублирующиеся ключи.2223*Полезная нагрузка* – это либо строковый объект, либо объект bytes в случае простых сообщений, либо список объектов [`EmailMessage`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage) для MIME-контейнеров, таких как *multipart/\** и *message/rfc822*.2425#### `class email.message.EmailMessage(policy=default)`2627Если указана *policy*, используются заданные ей правила для обновления и сериализации представления сообщения. Если *policy* не задана, используется политика [`default`](https://python-all.ru/3/library/email.policy.html#email.policy.default), которая следует правилам email RFC, за исключением окончаний строк (вместо требуемых RFC `\r\n` используются стандартные для Python окончания строк `\n`). Дополнительную информацию см. в документации [`policy`](https://python-all.ru/3/library/email.policy.html#module-email.policy). [\[2\]](https://python-all.ru/3/library/email.message.html#id4)2829#### `as_string(unixfrom=False, maxheaderlen=None, policy=None)`3031Возвращает всё сообщение, преобразованное в строку. Если необязательный параметр *unixfrom* равен true, в возвращаемую строку включается конвертный заголовок. *unixfrom* по умолчанию равен `False`. Для обратной совместимости с базовым классом [`Message`](https://python-all.ru/3/library/email.compat32-message.html#email.message.Message) принимается параметр *maxheaderlen*, но по умолчанию он равен `None`, что означает, что по умолчанию длина строки управляется [`max_line_length`](https://python-all.ru/3/library/email.policy.html#email.policy.Policy.max_line_length) политики. Аргумент *policy* может использоваться для переопределения политики по умолчанию, полученной из экземпляра сообщения. Это может быть использовано для управления форматированием, создаваемым методом, поскольку указанная *policy* будет передана в [`Generator`](https://python-all.ru/3/library/email.generator.html#email.generator.Generator).3233Преобразование сообщения может вызвать изменения в `EmailMessage`, если необходимо заполнить значения по умолчанию для завершения преобразования в строку (например, могут быть созданы или изменены MIME-границы).3435Обратите внимание, что этот метод предоставляется для удобства и может быть не самым полезным способом сериализации сообщений в вашем приложении, особенно если вы работаете с несколькими сообщениями. См. [`email.generator.Generator`](https://python-all.ru/3/library/email.generator.html#email.generator.Generator) для более гибкого API сериализации сообщений. Также обратите внимание, что этот метод ограничен созданием сообщений, сериализованных как "7 bit clean", когда [`utf8`](https://python-all.ru/3/library/email.policy.html#email.policy.EmailPolicy.utf8) равно `False`, что является значением по умолчанию.3637Изменено в версии 3.6: поведение по умолчанию, когда параметр *maxheaderlen* не указан, было изменено: вместо значения 0 по умолчанию теперь используется значение *max\_line\_length* из политики.3839#### `__str__()`4041Эквивалентно `as_string(policy=self.policy.clone(utf8=True))`. Позволяет `str(msg)` создать строку, содержащую сериализованное сообщение в удобочитаемом формате.4243Changed in version 3.4: the method was changed to use `utf8=True`, thus producing an [**RFC 6531**](https://python-all.ru/3/library/email.message.html)-like message representation, instead of being a direct alias for [`as_string()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.as_string).4445#### `as_bytes(unixfrom=False, policy=None)`4647Возвращает всё сообщение, преобразованное в объект bytes. Если необязательный параметр *unixfrom* равен true, в возвращаемую строку включается конвертный заголовок. *unixfrom* по умолчанию равен `False`. Аргумент *policy* может использоваться для переопределения политики по умолчанию, полученной из экземпляра сообщения. Это может быть использовано для управления форматированием, создаваемым методом, поскольку указанная *policy* будет передана в [`BytesGenerator`](https://python-all.ru/3/library/email.generator.html#email.generator.BytesGenerator).4849Преобразование сообщения может вызвать изменения в `EmailMessage`, если необходимо заполнить значения по умолчанию для завершения преобразования в строку (например, могут быть созданы или изменены MIME-границы).5051Обратите внимание, что этот метод предоставляется для удобства и может быть не самым полезным способом сериализации сообщений в вашем приложении, особенно если вы работаете с несколькими сообщениями. См. [`email.generator.BytesGenerator`](https://python-all.ru/3/library/email.generator.html#email.generator.BytesGenerator) для более гибкого API сериализации сообщений.5253#### `__bytes__()`5455Эквивалентно [`as_bytes()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.as_bytes). Позволяет `bytes(msg)` создать объект bytes, содержащий сериализованное сообщение.5657#### `is_multipart()`5859Возвращает `True`, если полезная нагрузка сообщения представляет собой список объектов sub-`EmailMessage`, в противном случае возвращает `False`. Когда `is_multipart()` возвращает `False`, полезная нагрузка должна быть строковым объектом (который может быть двоичной нагрузкой, закодированной с помощью CTE). Обратите внимание, что `is_multipart()` возвращающий `True` не обязательно означает, что “msg.get\_content\_maintype() == 'multipart'” вернёт `True`. Например, `is_multipart` вернёт `True`, когда `EmailMessage` имеет тип `message/rfc822`.6061#### `set_unixfrom(unixfrom)`6263Устанавливает конвертный заголовок сообщения равным *unixfrom*, который должен быть строкой. (См. [`mboxMessage`](https://python-all.ru/3/library/mailbox.html#mailbox.mboxMessage) для краткого описания этого заголовка.)6465#### `get_unixfrom()`6667Возвращает конвертный заголовок сообщения. По умолчанию равен `None`, если конвертный заголовок никогда не был установлен.6869Следующие методы реализуют интерфейс, подобный отображению (mapping), для доступа к заголовкам сообщения. Обратите внимание, что между этими методами и обычным интерфейсом отображения (т.е. словаря) есть некоторые семантические различия. Например, в словаре нет дублирующихся ключей, но здесь могут быть дублирующиеся заголовки сообщения. Кроме того, в словарях нет гарантированного порядка ключей, возвращаемых [`keys()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.keys), но в объекте `EmailMessage` заголовки всегда возвращаются в порядке их появления в исходном сообщении или в том порядке, в котором они были добавлены в сообщение позже. Любой заголовок, удалённый, а затем добавленный снова, всегда добавляется в конец списка заголовков.7071Эти семантические различия являются преднамеренными и направлены на удобство в наиболее распространённых случаях использования.7273Обратите внимание, что во всех случаях заголовки конверта, присутствующие в сообщении, не включаются в интерфейс отображения.7475#### `__len__()`7677Возвращает общее количество заголовков, включая дубликаты.7879#### `__contains__(name)`8081Возвращает `True`, если объект сообщения содержит поле с именем *name*. Сравнение выполняется без учёта регистра, и *name* не включает завершающее двоеточие. Используется для оператора `in`. Например:8283```python84if 'message-id' in myMessage:85 print('Message-ID:', myMessage['message-id'])86```8788#### `__getitem__(name)`8990Возвращает значение указанного поля заголовка. *name* не включает разделитель - двоеточие. Если заголовок отсутствует, возвращается `None`; исключение [`KeyError`](https://python-all.ru/3/library/exceptions.html#KeyError) никогда не возбуждается.9192Обратите внимание, что если указанное поле встречается в заголовках сообщения более одного раза, то точно не определено, какое из этих значений будет возвращено. Используйте метод [`get_all()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.get_all), чтобы получить значения всех существующих заголовков с именем *name*.9394При использовании стандартных (не `compat32`) политик возвращаемое значение является экземпляром подкласса [`email.headerregistry.BaseHeader`](https://python-all.ru/3/library/email.headerregistry.html#email.headerregistry.BaseHeader).9596#### `__setitem__(name, val)`9798Добавляет заголовок в сообщение с именем поля *name* и значением *val*. Поле добавляется в конец существующих заголовков сообщения.99100Обратите внимание, что это *не* перезаписывает и не удаляет существующие заголовки с тем же именем. Если требуется гарантировать, что новый заголовок будет единственным в сообщении с именем поля *name*, сначала удалите это поле, например:101102```python103del msg['subject']104msg['subject'] = 'Python roolz!'105```106107Если политика [`policy`](https://python-all.ru/3/library/email.policy.html#module-email.policy) определяет некоторые заголовки как уникальные (как это делают стандартные политики), данный метод может возбудить [`ValueError`](https://python-all.ru/3/library/exceptions.html#ValueError) при попытке присвоить значение такому заголовку, когда он уже существует. Такое поведение предусмотрено намеренно ради согласованности, но не стоит полагаться на него, поскольку в будущем мы можем сделать так, чтобы такие присваивания автоматически удаляли существующий заголовок.108109#### `__delitem__(name)`110111Удаляет все вхождения поля с именем *name* из заголовков сообщения. Исключение не возбуждается, если указанное поле отсутствует в заголовках.112113#### `keys()`114115Возвращает список всех имён полей заголовков сообщения.116117#### `values()`118119Возвращает список всех значений полей сообщения.120121#### `items()`122123Возвращает список кортежей из двух элементов, содержащих все заголовки и значения полей сообщения.124125#### `get(name, failobj=None)`126127Возвращает значение указанного поля заголовка. Это идентично [`__getitem__()`](https://python-all.ru/3/reference/datamodel.html#object.__getitem__), за исключением того, что в случае отсутствия указанного заголовка возвращается необязательный *failobj* (*failobj* по умолчанию равен `None`).128129Вот несколько дополнительных полезных методов, связанных с заголовками:130131#### `get_all(name, failobj=None)`132133Возвращает список всех значений для поля с именем *name*. Если в сообщении нет таких заголовков, возвращается *failobj* (по умолчанию `None`).134135#### `add_header(_name, _value, **_params)`136137Расширенная настройка заголовка. Этот метод похож на [`__setitem__()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.__setitem__), за исключением того, что дополнительные параметры заголовка можно передавать в виде именованных аргументов. *\_name* – это добавляемое поле заголовка, а *\_value* – *основное* значение заголовка.138139Для каждого элемента словаря именованных аргументов *\_params* ключ используется как имя параметра, причём символы подчёркивания преобразуются в дефисы (поскольку дефисы недопустимы в идентификаторах Python). Обычно параметр добавляется как `key="value"`, если только значение не равно `None`; в этом случае добавляется только ключ.140141Если значение содержит не-ASCII символы, кодировка и язык могут быть явно заданы указанием значения в виде тройки в формате `(CHARSET, LANGUAGE, VALUE)`, где `CHARSET` – строка, задающая кодировку для кодирования значения, `LANGUAGE` обычно может быть установлен в `None` или пустую строку (см. [**RFC 2231**](https://python-all.ru/3/library/email.message.html) для других возможностей), а `VALUE` – строковое значение, содержащее не-ASCII кодовые точки. Если тройка не передана и значение содержит не-ASCII символы, оно автоматически кодируется в формат [**RFC 2231**](https://python-all.ru/3/library/email.message.html) с использованием `CHARSET` `utf-8` и `LANGUAGE` `None`.142143Вот пример:144145```python146msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')147```148149Это добавит заголовок, который выглядит как150151```python152Content-Disposition: attachment; filename="bud.gif"153```154155Пример расширенного интерфейса с не-ASCII символами:156157```python158msg.add_header('Content-Disposition', 'attachment',159 filename=('iso-8859-1', '', 'Fußballer.ppt'))160```161162#### `replace_header(_name, _value)`163164Заменяет заголовок. Заменяет первый найденный в сообщении заголовок, соответствующий *\_name*, сохраняя порядок заголовков и регистр имени поля исходного заголовка. Если соответствующий заголовок не найден, возбуждается исключение [`KeyError`](https://python-all.ru/3/library/exceptions.html#KeyError).165166#### `get_content_type()`167168Возвращает тип содержимого сообщения, приведённый к нижнему регистру в формате *maintype/subtype*. Если в сообщении нет заголовка *Content-Type*, возвращается значение, возвращаемое [`get_default_type()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.get_default_type). Если заголовок *Content-Type* некорректен, возвращается `text/plain`.169170(Согласно [**RFC 2045**](https://python-all.ru/3/library/email.message.html), сообщения всегда имеют тип по умолчанию, `get_content_type()` всегда возвращает некоторое значение. [**RFC 2045**](https://python-all.ru/3/library/email.message.html) определяет тип по умолчанию для сообщения как *text/plain*, если оно не находится внутри контейнера *multipart/digest*; в этом случае типом по умолчанию будет *message/rfc822*. Если заголовок *Content-Type* содержит некорректное описание типа, [**RFC 2045**](https://python-all.ru/3/library/email.message.html) предписывает использовать тип по умолчанию *text/plain*.)171172#### `get_content_maintype()`173174Возвращает основной тип содержимого сообщения. Это часть *maintype* строки, возвращаемой [`get_content_type()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.get_content_type).175176#### `get_content_subtype()`177178Возвращает подтип содержимого сообщения. Это часть *subtype* строки, возвращаемой [`get_content_type()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.get_content_type).179180#### `get_default_type()`181182Возвращает тип содержимого по умолчанию. Большинство сообщений имеют тип содержимого по умолчанию *text/plain*, за исключением сообщений, которые являются подчастями контейнеров *multipart/digest*. Такие подчасти имеют тип содержимого по умолчанию *message/rfc822*.183184#### `set_default_type(ctype)`185186Устанавливает тип содержимого по умолчанию. *ctype* должен быть либо *text/plain*, либо *message/rfc822*, хотя это не контролируется. Тип содержимого по умолчанию не хранится в заголовке *Content-Type*, поэтому он влияет только на возвращаемое значение методов `get_content_type`, когда в сообщении отсутствует заголовок *Content-Type*.187188#### `set_param(param, value, header='Content-Type', requote=True, charset=None, language='', replace=False)`189190Устанавливает параметр в заголовке *Content-Type*. Если параметр уже существует в заголовке, заменяет его значение на *value*. Когда *header* равен `Content-Type` (по умолчанию) и заголовок ещё не существует в сообщении, он добавляется, его значение устанавливается в *text/plain*, и добавляется новое значение параметра. Необязательный параметр *header* указывает альтернативный заголовок вместо *Content-Type*.191192Если значение содержит не-ASCII символы, кодировка и язык могут быть явно указаны с помощью необязательных параметров *charset* и *language*. Необязательный параметр *language* задаёт язык [**RFC 2231**](https://python-all.ru/3/library/email.message.html), по умолчанию – пустая строка. Оба параметра *charset* и *language* должны быть строками. По умолчанию используется `utf8` *charset* и `None` для *language*.193194Если *replace* равен `False` (по умолчанию), заголовок перемещается в конец списка заголовков. Если *replace* равен `True`, заголовок будет обновлён на месте.195196Использование параметра *requote* с объектами `EmailMessage` устарело.197198Обратите внимание, что существующие значения параметров заголовков могут быть получены через атрибут [`params`](https://python-all.ru/3/library/email.headerregistry.html#email.headerregistry.ParameterizedMIMEHeader.params) значения заголовка (например, `msg['Content-Type'].params['charset']`).199200Изменено в версии 3.4: `replace` добавлен ключевой параметр.201202#### `del_param(param, header='content-type', requote=True)`203204Полностью удаляет указанный параметр из заголовка *Content-Type*. Заголовок будет перезаписан на месте без этого параметра и его значения. Необязательный параметр *header* указывает альтернативный заголовок вместо *Content-Type*.205206Использование параметра *requote* с объектами `EmailMessage` устарело.207208#### `get_filename(failobj=None)`209210Возвращает значение параметра `filename` заголовка *Content-Disposition* сообщения. Если в заголовке нет параметра `filename`, этот метод пытается найти параметр `name` в заголовке *Content-Type*. Если ни один из них не найден или заголовок отсутствует, возвращается *failobj*. Возвращаемая строка всегда будет раскрыта в соответствии с [`email.utils.unquote()`](https://python-all.ru/3/library/email.utils.html#email.utils.unquote).211212#### `get_boundary(failobj=None)`213214Возвращает значение параметра `boundary` заголовка *Content-Type* сообщения или *failobj*, если заголовок отсутствует или не содержит параметра `boundary`. Возвращаемая строка всегда будет раскрыта в соответствии с [`email.utils.unquote()`](https://python-all.ru/3/library/email.utils.html#email.utils.unquote).215216#### `set_boundary(boundary)`217218Устанавливает параметр `boundary` заголовка *Content-Type* в значение *boundary*. `set_boundary()` всегда будет заключать *boundary* в кавычки при необходимости. Возбуждается исключение [`HeaderParseError`](https://python-all.ru/3/library/email.errors.html#email.errors.HeaderParseError), если объект сообщения не имеет заголовка *Content-Type*.219220Обратите внимание, что использование этого метода незначительно отличается от удаления старого заголовка *Content-Type* и добавления нового с новой границей через [`add_header()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.add_header), поскольку `set_boundary()` сохраняет порядок заголовка *Content-Type* в списке заголовков.221222#### `get_content_charset(failobj=None)`223224Возвращает параметр `charset` заголовка *Content-Type*, приведённый к нижнему регистру. Если заголовок *Content-Type* отсутствует или не содержит параметра `charset`, возвращается *failobj*.225226#### `get_charsets(failobj=None)`227228Возвращает список, содержащий имена наборов символов в сообщении. Если сообщение является *multipart*, список будет содержать по одному элементу для каждой вложенной части в полезной нагрузке; в противном случае это будет список длиной 1.229230Каждый элемент списка представляет собой строку – значение параметра `charset` в заголовке *Content-Type* для соответствующей подчасти. Если у подчасти нет заголовка *Content-Type*, параметра `charset` или она не относится к основному MIME-типу *text*, то этот элемент возвращаемого списка будет равен *failobj*.231232#### `is_attachment()`233234Возвращает `True`, если присутствует заголовок *Content-Disposition* и его значение (без учёта регистра) равно `attachment`, иначе `False`.235236Изменено в версии 3.4.2: is\_attachment теперь метод, а не свойство, для согласованности с [`is_multipart()`](https://python-all.ru/3/library/email.compat32-message.html#email.message.Message.is_multipart).237238#### `get_content_disposition()`239240Возвращает значение заголовка *Content-Disposition* сообщения в нижнем регистре (без параметров), если он есть, или `None`. Возможные значения этого метода: *inline*, *attachment* или `None`, если сообщение соответствует [**RFC 2183**](https://python-all.ru/3/library/email.message.html).241242Добавлено в версии 3.5.243244Следующие методы относятся к запросу и изменению содержимого (полезной нагрузки) сообщения.245246#### `walk()`247248Метод `walk()` – это универсальный генератор, который можно использовать для обхода всех частей и подчастей дерева объекта сообщения в порядке прямого обхода в глубину. Обычно `walk()` используется как итератор в цикле `for`; каждая итерация возвращает следующую подчасть.249250Вот пример, который выводит MIME-тип каждой части многокомпонентной структуры сообщения:251252```pycon253>>> for part in msg.walk():254... print(part.get_content_type())255multipart/report256text/plain257message/delivery-status258text/plain259text/plain260message/rfc822261text/plain262```263264`walk` обходит подчасти любой части, для которой [`is_multipart()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.is_multipart) возвращает `True`, даже если `msg.get_content_maintype() == 'multipart'` может возвращать `False`. Это видно в нашем примере при использовании отладочной вспомогательной функции `_structure`:265266```pycon267>>> from email.iterators import _structure268>>> for part in msg.walk():269... print(part.get_content_maintype() == 'multipart',270... part.is_multipart())271True True272False False273False True274False False275False False276False True277False False278>>> _structure(msg)279multipart/report280 text/plain281 message/delivery-status282 text/plain283 text/plain284 message/rfc822285 text/plain286```287288Здесь части `message` не являются `multiparts`, но содержат подчасти. `is_multipart()` возвращает `True`, а `walk` спускается в подчасти.289290#### `get_body(preferencelist=('related', 'html', 'plain'))`291292Возвращает MIME-часть, которая наилучшим образом подходит на роль «тела» сообщения.293294*preferencelist* должен быть последовательностью строк из набора `related`, `html` и `plain` и указывает порядок предпочтения типа содержимого возвращаемой части.295296Поиск подходящих кандидатов начинается с объекта, для которого вызван метод `get_body`.297298Если `related` не включён в *preferencelist*, корневая часть (или подчасть корневой части) любой встреченной связанной части рассматривается как кандидат, если эта (под)часть соответствует предпочтению.299300При обнаружении `multipart/related` проверяется параметр `start`, и если найдена часть с соответствующим *Content-ID*, то при поиске подходящих кандидатов рассматривается только она. В противном случае рассматривается только первая (корневая по умолчанию) часть `multipart/related`.301302Если часть имеет заголовок *Content-Disposition*, то часть считается подходящим кандидатом только если значение заголовка равно `inline`.303304Если ни один из кандидатов не соответствует ни одному предпочтению из *preferencelist*, возвращается `None`.305306Примечания: (1) Для большинства приложений единственные осмысленные комбинации *preferencelist* – это `('plain',)`, `('html', 'plain')` и значение по умолчанию `('related', 'html', 'plain')`. (2) Поскольку поиск начинается с объекта, для которого вызван `get_body`, вызов `get_body` на `multipart/related` вернёт сам объект, если только *preferencelist* не имеет нестандартного значения. (3) Сообщения (или части сообщения), которые не указывают *Content-Type* или имеют некорректный заголовок *Content-Type*, обрабатываются так, как будто они имеют тип `text/plain`, что иногда может привести к неожиданным результатам при вызове `get_body`.307308#### `iter_attachments()`309310Return an iterator over all of the immediate sub-parts of the message that are not candidate “body” parts. That is, skip the first occurrence of each of `text/plain`, `text/html`, `multipart/related`, or `multipart/alternative` (unless they are explicitly marked as attachments via *Content-Disposition: attachment*), and return all remaining parts. When applied directly to a `multipart/related`, return an iterator over the all the related parts except the root part (ie: the part pointed to by the `start` parameter, or the first part if there is no `start` parameter or the `start` parameter doesn’t match the *Content-ID* of any of the parts). When applied directly to a `multipart/alternative` or a non-`multipart`, return an empty iterator.311312#### `iter_parts()`313314Возвращает итератор по всем непосредственным подчастям сообщения; для не-`multipart` итератор будет пустым. (См. также [`walk()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.walk).)315316#### `get_content(*args, content_manager=None, **kw)`317318Вызывает метод [`get_content()`](https://python-all.ru/3/library/email.contentmanager.html#email.contentmanager.ContentManager.get_content) объекта *content\_manager*, передавая self как объект сообщения, а также любые другие аргументы и ключевые слова в качестве дополнительных аргументов. Если *content\_manager* не указан, используется `content_manager`, заданный текущим [`policy`](https://python-all.ru/3/library/email.policy.html#module-email.policy).319320#### `set_content(*args, content_manager=None, **kw)`321322Вызывает метод [`set_content()`](https://python-all.ru/3/library/email.contentmanager.html#email.contentmanager.ContentManager.set_content) объекта *content\_manager*, передавая self как объект сообщения, а также любые другие аргументы и ключевые слова в качестве дополнительных аргументов. Если *content\_manager* не указан, используется `content_manager`, заданный текущим [`policy`](https://python-all.ru/3/library/email.policy.html#module-email.policy).323324#### `make_related(boundary=None)`325326Преобразует сообщение, не являющееся `multipart`, в сообщение `multipart/related`, перемещая все существующие заголовки *Content-* и полезную нагрузку в (новую) первую часть `multipart`. Если указан *boundary*, он используется в качестве строки границы в multipart, в противном случае граница будет создана автоматически при необходимости (например, при сериализации сообщения).327328#### `make_alternative(boundary=None)`329330Преобразует сообщение, не являющееся `multipart` или являющееся `multipart/related`, в сообщение `multipart/alternative`, перемещая все существующие заголовки *Content-* и полезную нагрузку в (новую) первую часть `multipart`. Если указан *boundary*, он используется в качестве строки границы в multipart, в противном случае граница будет создана автоматически при необходимости (например, при сериализации сообщения).331332#### `make_mixed(boundary=None)`333334Преобразует сообщение, не являющееся `multipart`, являющееся `multipart/related` или `multipart-alternative`, в сообщение `multipart/mixed`, перемещая все существующие заголовки *Content-* и полезную нагрузку в (новую) первую часть `multipart`. Если указан *boundary*, он используется в качестве строки границы в multipart, в противном случае граница будет создана автоматически при необходимости (например, при сериализации сообщения).335336#### `add_related(*args, content_manager=None, **kw)`337338Если сообщение является `multipart/related`, создаётся новый объект сообщения, все аргументы передаются его методу [`set_content()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.set_content), и [`attach()`](https://python-all.ru/3/library/email.compat32-message.html#email.message.Message.attach) его к `multipart`. Если сообщение не является `multipart`, вызывается [`make_related()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.make_related), после чего выполняется описанное выше. Если сообщение относится к любому другому типу `multipart`, возбуждается [`TypeError`](https://python-all.ru/3/library/exceptions.html#TypeError). Если *content\_manager* не указан, используется `content_manager`, заданный текущим [`policy`](https://python-all.ru/3/library/email.policy.html#module-email.policy). Если у добавленной части нет заголовка *Content-Disposition*, добавляется заголовок со значением `inline`.339340#### `add_alternative(*args, content_manager=None, **kw)`341342Если сообщение является `multipart/alternative`, создаётся новый объект сообщения, все аргументы передаются его методу [`set_content()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.set_content), и [`attach()`](https://python-all.ru/3/library/email.compat32-message.html#email.message.Message.attach) его к `multipart`. Если сообщение не является `multipart` или является `multipart/related`, вызывается [`make_alternative()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.make_alternative), после чего выполняется описанное выше. Если сообщение относится к любому другому типу `multipart`, возбуждается [`TypeError`](https://python-all.ru/3/library/exceptions.html#TypeError). Если *content\_manager* не указан, используется `content_manager`, заданный текущим [`policy`](https://python-all.ru/3/library/email.policy.html#module-email.policy).343344#### `add_attachment(*args, content_manager=None, **kw)`345346Если сообщение является `multipart/mixed`, создаётся новый объект сообщения, все аргументы передаются его методу [`set_content()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.set_content), и [`attach()`](https://python-all.ru/3/library/email.compat32-message.html#email.message.Message.attach) его к `multipart`. Если сообщение не является `multipart`, `multipart/related` или `multipart/alternative`, вызывается [`make_mixed()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.make_mixed), после чего выполняется описанное выше. Если *content\_manager* не указан, используется `content_manager`, заданный текущим [`policy`](https://python-all.ru/3/library/email.policy.html#module-email.policy). Если у добавленной части нет заголовка *Content-Disposition*, добавляется заголовок со значением `attachment`. Этот метод можно использовать как для явных вложений (*Content-Disposition: attachment*), так и для `inline` вложений (*Content-Disposition: inline*), передавая соответствующие параметры в `content_manager`.347348#### `clear()`349350Удаляет полезную нагрузку и все заголовки.351352#### `clear_content()`353354Удаляет полезную нагрузку и все заголовки *!Content-*, оставляя все остальные заголовки нетронутыми и в исходном порядке.355356Объекты `EmailMessage` имеют следующие атрибуты экземпляра:357358#### `preamble`359360Формат MIME-документа допускает наличие некоторого текста между пустой строкой после заголовков и первой строкой границы multipart. Обычно этот текст не виден в MIME-совместимом почтовом клиенте, поскольку он находится вне стандартной MIME-защиты. Однако при просмотре необработанного текста сообщения или при просмотре сообщения в клиенте, не поддерживающем MIME, этот текст может стать видимым.361362Атрибут *preamble* содержит этот дополнительный текст за пределами MIME-защиты для MIME-документов. Когда [`Parser`](https://python-all.ru/3/library/email.parser.html#email.parser.Parser) обнаруживает некоторый текст после заголовков, но до первой строки границы, он присваивает этот текст атрибуту *preamble* сообщения. Когда [`Generator`](https://python-all.ru/3/library/email.generator.html#email.generator.Generator) записывает текстовое представление MIME-сообщения и обнаруживает, что сообщение имеет атрибут *preamble*, он записывает этот текст в области между заголовками и первой границей. Подробнее см. [`email.parser`](https://python-all.ru/3/library/email.parser.html#module-email.parser) и [`email.generator`](https://python-all.ru/3/library/email.generator.html#module-email.generator).363364Обратите внимание: если у объекта сообщения нет преамбулы, атрибут *preamble* будет равен `None`.365366#### `epilogue`367368Атрибут *epilogue* действует так же, как атрибут *preamble*, за исключением того, что он содержит текст, который появляется между последней границей и концом сообщения. Как и в случае с [`preamble`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.preamble), если текст эпилога отсутствует, этот атрибут будет равен `None`.369370#### `defects`371372Атрибут *defects* содержит список всех проблем, обнаруженных при разборе этого сообщения. См. [`email.errors`](https://python-all.ru/3/library/email.errors.html#module-email.errors) для подробного описания возможных дефектов разбора.373374#### `class email.message.MIMEPart(policy=default)`375376Этот класс представляет подчасть MIME-сообщения. Он идентичен [`EmailMessage`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage), за исключением того, что заголовки *MIME-Version* не добавляются при вызове [`set_content()`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage.set_content), поскольку подчасти не нуждаются в собственных заголовках *MIME-Version*.377378Сноски379380\[[1](https://python-all.ru/3/library/email.message.html#id1)\]381382Изначально добавлено в 3.4 как [временный модуль](https://python-all.ru/3/glossary.html#term-provisional-package). Документация для устаревшего класса сообщений перемещена в [email.message.Message: Представление email-сообщения с использованием compat32 API](https://python-all.ru/3/library/email.compat32-message.html#compat32-message).383384\[[2](https://python-all.ru/3/library/email.message.html#id2)\]385386Класс [`EmailMessage`](https://python-all.ru/3/library/email.message.html#email.message.EmailMessage) требует политику, которая предоставляет атрибут `content_manager` для работы методов управления содержимым, таких как `set_content()` и `get_content()`. Устаревшая политика [`compat32`](https://python-all.ru/3/library/email.policy.html#email.policy.compat32) не поддерживает эти методы и не должна использоваться с `EmailMessage`.387