email.message.md
1> **Источник:** https://python-all.ru/3.3/library/email.message.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 19.1.1. [`email.message`](https://python-all.ru/3.3/library/email.message.html#module-email.message): Представление email-сообщения89Центральный класс в пакете [`email`](https://python-all.ru/3.3/library/email.html#module-email) – это класс [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message), импортируемый из модуля [`email.message`](https://python-all.ru/3.3/library/email.message.html#module-email.message). Он является базовым классом для объектной модели [`email`](https://python-all.ru/3.3/library/email.html#module-email). [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message) предоставляет основную функциональность для установки и запроса полей заголовков, а также для доступа к телам сообщений.1011Conceptually, a [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message) object consists of *headers* and *payloads*. Headers are [**RFC 2822**](https://python-all.ru/3.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.1213Заголовки хранятся и возвращаются с сохранением регистра, но сравнение выполняется без учёта регистра. Также может присутствовать один конвертный заголовок, также известный как заголовок *Unix-From* или заголовок `From_`. Полезная нагрузка представляет собой либо строку в случае простых объектов сообщений, либо список объектов [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message) для MIME-контейнерных документов (например, *multipart/\** и *message/rfc822*).1415Объекты [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message) предоставляют интерфейс в стиле отображения для доступа к заголовкам сообщения и явный интерфейс для доступа как к заголовкам, так и к полезной нагрузке. Они предоставляют удобные методы для создания плоского текстового представления дерева объектов сообщения, для доступа к часто используемым параметрам заголовков и для рекурсивного обхода дерева объектов.1617Вот методы класса [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message):1819#### `class email.message.Message(policy=compat32)`2021Аргумент *policy* определяет [`политику`](https://python-all.ru/3.3/library/email.policy.html#module-email.policy), которая будет использоваться для обновления модели сообщения. Значение по умолчанию [`compat32`](https://python-all.ru/3.3/library/email.policy.html#email.policy.Compat32) обеспечивает обратную совместимость с версией Python 3.2 пакета email. Дополнительные сведения см. в документации [`policy`](https://python-all.ru/3.3/library/email.policy.html#module-email.policy).2223Изменено в версии 3.3: Был добавлен именованный аргумент *policy*.2425#### `as_string(unixfrom=False, maxheaderlen=0)`2627Возвращает все сообщение, преобразованное в строку. Если необязательный *unixfrom* равен `True`, в возвращаемую строку включается заголовок конверта. *unixfrom* по умолчанию равен `False`. Преобразование сообщения может привести к изменениям [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message), если необходимо заполнить значения по умолчанию для завершения преобразования в строку (например, могут быть созданы или изменены MIME-границы).2829Обратите внимание, что этот метод предоставляется для удобства и может не всегда форматировать сообщение так, как вам нужно. Например, по умолчанию он не выполняет преобразование строк, начинающихся с `From`, которое требуется форматом unix mbox. Для большей гибкости создайте экземпляр [`Generator`](https://python-all.ru/3.3/library/email.generator.html#email.generator.Generator) и используйте его метод [`flatten()`](https://python-all.ru/3.3/library/email.generator.html#email.generator.Generator.flatten) напрямую. Например:3031```python32from io import StringIO33from email.generator import Generator34fp = StringIO()35g = Generator(fp, mangle_from_=True, maxheaderlen=60)36g.flatten(msg)37text = fp.getvalue()38```3940#### `__str__()`4142Эквивалентно `as_string(unixfrom=True)`.4344#### `is_multipart()`4546Возвращает `True`, если содержимое сообщения является списком вложенных объектов [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message), в противном случае возвращает `False`. Когда [`is_multipart()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.is_multipart) возвращает `False`, содержимое должно быть строковым объектом.4748#### `set_unixfrom(unixfrom)`4950Устанавливает конвертный заголовок сообщения равным *unixfrom*, который должен быть строкой.5152#### `get_unixfrom()`5354Возвращает конвертный заголовок сообщения. По умолчанию равен `None`, если конвертный заголовок никогда не был установлен.5556#### `attach(payload)`5758Добавляет указанную *полезную нагрузку* к текущей полезной нагрузке, которая перед вызовом должна быть `None` или списком объектов [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message). После вызова полезная нагрузка всегда будет списком объектов [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message). Если нужно установить полезную нагрузку в скалярный объект (например, строку), используйте [`set_payload()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.set_payload).5960#### `get_payload(i=None, decode=False)`6162Возвращает текущую полезную нагрузку, которая будет списком объектов [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message), когда [`is_multipart()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.is_multipart) равно `True`, или строкой, когда [`is_multipart()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.is_multipart) равно `False`. Если полезная нагрузка является списком и вы изменяете объект списка, вы изменяете полезную нагрузку сообщения на месте.6364С необязательным аргументом *i*, [`get_payload()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.get_payload) вернёт *i*-й элемент полезной нагрузки, считая с нуля, если [`is_multipart()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.is_multipart) равно `True`. Будет возбуждено исключение [`IndexError`](https://python-all.ru/3.3/library/exceptions.html#IndexError), если *i* меньше 0 или больше или равно количеству элементов в полезной нагрузке. Если полезная нагрузка является строкой (т.е. [`is_multipart()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.is_multipart) равно `False`) и указан *i*, возбуждается [`TypeError`](https://python-all.ru/3.3/library/exceptions.html#TypeError).6566Необязательный *decode* – это флаг, указывающий, следует ли декодировать полезную нагрузку в соответствии с заголовком *Content-Transfer-Encoding*. Когда `True` и сообщение не является multipart-сообщением, полезная нагрузка будет декодирована, если значение этого заголовка – `quoted-printable` или `base64`. Если используется другая кодировка или заголовок *Content-Transfer-Encoding* отсутствует, полезная нагрузка возвращается как есть (без декодирования). Во всех случаях возвращаемое значение – бинарные данные. Если сообщение является multipart и флаг *decode* равен `True`, то возвращается `None`. Если полезная нагрузка закодирована в base64 и не является правильно сформированной (отсутствует дополнение, символы вне алфавита base64), то соответствующее нарушение будет добавлено в свойство defect сообщения (соответственно `InvalidBase64PaddingDefect` или `InvalidBase64CharactersDefect`).6768Когда *decode* равен `False` (по умолчанию), тело возвращается в виде строки без декодирования заголовка *Content-Transfer-Encoding*. Однако для кодировки *Content-Transfer-Encoding* со значением 8bit предпринимается попытка декодировать исходные байты с использованием кодировки `charset`, указанной в заголовке *Content-Type*, с использованием обработчика ошибок `replace`. Если кодировка `charset` не указана или указанная кодировка `charset` не распознана пакетом email, тело декодируется с использованием кодировки ASCII по умолчанию.6970#### `set_payload(payload, charset=None)`7172Устанавливает полезную нагрузку всего объекта сообщения в *payload*. Ответственность за соблюдение инвариантов полезной нагрузки лежит на клиенте. Необязательный параметр *charset* задаёт набор символов сообщения по умолчанию; подробнее см. [`set_charset()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.set_charset).7374#### `set_charset(charset)`7576Устанавливает набор символов полезной нагрузки в *charset*, который может быть либо экземпляром [`Charset`](https://python-all.ru/3.3/library/email.charset.html#email.charset.Charset) (см. [`email.charset`](https://python-all.ru/3.3/library/email.charset.html#module-email.charset)), либо строкой с именем набора символов, либо `None`. Если это строка, она будет преобразована в экземпляр [`Charset`](https://python-all.ru/3.3/library/email.charset.html#email.charset.Charset). Если *charset* равен `None`, параметр `charset` будет удалён из заголовка *Content-Type* (в остальном сообщение не изменится). Любое другое значение вызовет [`TypeError`](https://python-all.ru/3.3/library/exceptions.html#TypeError).7778Если отсутствует заголовок *MIME-Version*, он будет добавлен. Если отсутствует заголовок *Content-Type*, он будет добавлен со значением *text/plain*. Независимо от того, существует ли заголовок *Content-Type*, его параметр `charset` будет установлен в *charset.output\_charset*. Если *charset.input\_charset* и *charset.output\_charset* различаются, полезная нагрузка будет перекодирована в *output\_charset*. Если не существует заголовка *Content-Transfer-Encoding*, то полезная нагрузка будет трансферно закодирована, если необходимо, с использованием указанного [`Charset`](https://python-all.ru/3.3/library/email.charset.html#email.charset.Charset), и будет добавлен заголовок с соответствующим значением. Если заголовок *Content-Transfer-Encoding* уже существует, предполагается, что полезная нагрузка уже правильно закодирована с использованием этого *Content-Transfer-Encoding*, и она не изменяется.7980#### `get_charset()`8182Возвращает экземпляр [`Charset`](https://python-all.ru/3.3/library/email.charset.html#email.charset.Charset), связанный с полезной нагрузкой сообщения.8384Следующие методы реализуют интерфейс, подобный отображению (mapping), для доступа к заголовкам сообщения [**RFC 2822**](https://python-all.ru/3.3/library/email.message.html). Обратите внимание, что между этими методами и обычным интерфейсом отображения (т.е. словаря) есть некоторые семантические различия. Например, в словаре нет повторяющихся ключей, но здесь могут быть повторяющиеся заголовки сообщения. Также в словарях нет гарантированного порядка ключей, возвращаемых [`keys()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.keys), но в объекте [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message) заголовки всегда возвращаются в том порядке, в котором они появились в исходном сообщении или были добавлены позже. Любой удалённый и затем повторно добавленный заголовок всегда добавляется в конец списка заголовков.8586Эти семантические различия являются намеренными и направлены на максимальное удобство.8788Обратите внимание, что во всех случаях заголовки конверта, присутствующие в сообщении, не включаются в интерфейс отображения.8990В модели, созданной из байтов, любые значения заголовков, которые (в нарушение RFC) содержат не-ASCII байты, при получении через этот интерфейс будут представлены как объекты [`Header`](https://python-all.ru/3.3/library/email.header.html#email.header.Header) с кодировкой *unknown-8bit*.9192#### `__len__()`9394Возвращает общее количество заголовков, включая дубликаты.9596#### `__contains__(name)`9798Возвращает истину, если объект сообщения имеет поле с именем *name*. Сравнение выполняется без учёта регистра, и *name* не должно включать завершающее двоеточие. Используется для оператора `in`, например:99100```python101if 'message-id' in myMessage:102 print('Message-ID:', myMessage['message-id'])103```104105#### `__getitem__(name)`106107Возвращает значение указанного поля заголовка. *name* не должно включать разделитель полей – двоеточие. Если заголовок отсутствует, возвращается `None`; исключение [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError) никогда не вызывается.108109Обратите внимание: если указанное поле встречается в заголовках сообщения более одного раза, то какое именно из этих значений будет возвращено, не определено. Используйте метод [`get_all()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.get_all), чтобы получить значения всех существующих заголовков с этим именем.110111#### `__setitem__(name, val)`112113Добавляет заголовок в сообщение с именем поля *name* и значением *val*. Поле добавляется в конец существующих полей сообщения.114115Обратите внимание, что это *не* перезаписывает и не удаляет существующие заголовки с тем же именем. Если требуется гарантировать, что новый заголовок будет единственным в сообщении с именем поля *name*, сначала удалите это поле, например:116117```python118del msg['subject']119msg['subject'] = 'Python roolz!'120```121122#### `__delitem__(name)`123124Удаляет все вхождения поля с именем *name* из заголовков сообщения. Исключение не возбуждается, если указанное поле отсутствует в заголовках.125126#### `keys()`127128Возвращает список всех имён полей заголовков сообщения.129130#### `values()`131132Возвращает список всех значений полей сообщения.133134#### `items()`135136Возвращает список кортежей из двух элементов, содержащих все заголовки и значения полей сообщения.137138#### `get(name, failobj=None)`139140Возвращает значение указанного поля заголовка. Этот метод идентичен [`__getitem__()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.__getitem__), за исключением того, что если указанный заголовок отсутствует, возвращается необязательный параметр *failobj* (по умолчанию `None`).141142Вот несколько дополнительных полезных методов:143144#### `get_all(name, failobj=None)`145146Возвращает список всех значений для поля с именем *name*. Если в сообщении нет таких заголовков, возвращается *failobj* (по умолчанию `None`).147148#### `add_header(_name, _value, **_params)`149150Расширенная установка заголовка. Этот метод похож на [`__setitem__()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.__setitem__), за исключением того, что дополнительные параметры заголовка могут быть переданы в виде именованных аргументов. *\_name* – это добавляемое поле заголовка, а *\_value* – это *основное* значение заголовка.151152Для каждого элемента в словаре именованных аргументов *\_params* ключ принимается как имя параметра, при этом символы подчёркивания преобразуются в дефисы (поскольку дефисы недопустимы в идентификаторах Python). Обычно параметр добавляется как `key="value"`, если только значение не равно `None`; в этом случае добавляется только ключ. Если значение содержит не-ASCII символы, его можно указать в виде тройки в формате `(CHARSET, LANGUAGE, VALUE)`, где `CHARSET` – это строка, задающая кодировку для кодирования значения, `LANGUAGE` обычно может быть установлен в `None` или пустую строку (см. [**RFC 2231**](https://python-all.ru/3.3/library/email.message.html) для других возможностей), а `VALUE` – это строковое значение, содержащее не-ASCII кодовые точки. Если тройка не передана и значение содержит не-ASCII символы, оно автоматически кодируется в формате [**RFC 2231**](https://python-all.ru/3.3/library/email.message.html) с использованием кодировки `CHARSET` `utf-8` и языка `LANGUAGE`, равного `None`.153154Вот пример:155156```python157msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')158```159160Это добавит заголовок, который выглядит как161162```python163Content-Disposition: attachment; filename="bud.gif"164```165166Пример с не-ASCII символами:167168```python169msg.add_header('Content-Disposition', 'attachment',170 filename=('iso-8859-1', '', 'Fußballer.ppt'))171```172173Что даёт174175```python176Content-Disposition: attachment; filename*="iso-8859-1''Fu%DFballer.ppt"177```178179#### `replace_header(_name, _value)`180181Заменяет заголовок. Заменяет первый найденный в сообщении заголовок, который соответствует *\_name*, сохраняя порядок заголовков и регистр имени поля. Если соответствующий заголовок не найден, вызывается [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError).182183#### `get_content_type()`184185Возвращает тип содержимого сообщения. Возвращаемая строка приводится к нижнему регистру и имеет вид *maintype/subtype*. Если в сообщении не было заголовка *Content-Type*, будет возвращён тип по умолчанию, задаваемый [`get_default_type()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.get_default_type). Поскольку согласно [**RFC 2045**](https://python-all.ru/3.3/library/email.message.html) сообщения всегда имеют тип по умолчанию, [`get_content_type()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.get_content_type) всегда возвращает значение.186187[**RFC 2045**](https://python-all.ru/3.3/library/email.message.html) определяет тип по умолчанию сообщения как *text/plain*, если только оно не находится внутри контейнера *multipart/digest*, в этом случае он будет *message/rfc822*. Если заголовок *Content-Type* содержит недопустимую спецификацию типа, [**RFC 2045**](https://python-all.ru/3.3/library/email.message.html) предписывает, что типом по умолчанию должен быть *text/plain*.188189#### `get_content_maintype()`190191Возвращает основной тип содержимого сообщения. Это часть *maintype* строки, возвращаемой [`get_content_type()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.get_content_type).192193#### `get_content_subtype()`194195Возвращает подтип содержимого сообщения. Это часть *subtype* строки, возвращаемой [`get_content_type()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.get_content_type).196197#### `get_default_type()`198199Возвращает тип содержимого по умолчанию. Большинство сообщений имеют тип содержимого по умолчанию *text/plain*, за исключением сообщений, которые являются подчастями контейнеров *multipart/digest*. Такие подчасти имеют тип содержимого по умолчанию *message/rfc822*.200201#### `set_default_type(ctype)`202203Устанавливает тип содержимого по умолчанию. *ctype* должен быть либо *text/plain*, либо *message/rfc822*, хотя это не принудительно. Тип содержимого по умолчанию не хранится в заголовке *Content-Type*.204205#### `get_params(failobj=None, header='content-type', unquote=True)`206207Возвращает параметры заголовка *Content-Type* сообщения в виде списка. Элементы возвращаемого списка – это кортежи из двух элементов (ключ, значение), разделённые знаком `'='`. Левая часть `'='` – это ключ, правая – значение. Если в параметре нет знака `'='`, значением будет пустая строка; иначе значение определяется так, как описано в [`get_param()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.get_param), и при этом снимаются кавычки, если необязательный параметр *unquote* равен `True` (по умолчанию).208209Необязательный параметр *failobj* – объект, возвращаемый при отсутствии заголовка *Content-Type*. Необязательный параметр *header* – заголовок, который нужно искать вместо *Content-Type*.210211#### `get_param(param, failobj=None, header='content-type', unquote=True)`212213Возвращает значение параметра *param* заголовка *Content-Type* в виде строки. Если в сообщении нет заголовка *Content-Type* или такого параметра не существует, возвращается *failobj* (по умолчанию `None`).214215Необязательный параметр *header*, если указан, задаёт заголовок сообщения, который следует использовать вместо *Content-Type*.216217Ключи параметров всегда сравниваются без учёта регистра. Возвращаемое значение может быть либо строкой, либо кортежем из трёх элементов, если параметр был закодирован по [**RFC 2231**](https://python-all.ru/3.3/library/email.message.html). Если это кортеж из трёх элементов, то элементы значения имеют вид `(CHARSET, LANGUAGE, VALUE)`. Обратите внимание, что как `CHARSET`, так и `LANGUAGE` могут быть `None`; в этом случае следует считать, что `VALUE` закодирован в кодировке `us-ascii`. Обычно параметр `LANGUAGE` можно игнорировать.218219Если приложению не важно, был ли параметр закодирован по [**RFC 2231**](https://python-all.ru/3.3/library/email.message.html), можно свернуть значение параметра вызовом [`email.utils.collapse_rfc2231_value()`](https://python-all.ru/3.3/library/email.util.html#email.utils.collapse_rfc2231_value), передав возвращаемое значение от [`get_param()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.get_param). Этот вызов вернёт корректно декодированную строку Unicode, если значение было кортежем, или исходную строку без кавычек в противном случае. Пример:220221```python222rawparam = msg.get_param('foo')223param = email.utils.collapse_rfc2231_value(rawparam)224```225226В любом случае значение параметра (возвращаемая строка или элемент `VALUE` кортежа из трёх) всегда возвращается без кавычек, если только *unquote* не равен `False`.227228#### `set_param(param, value, header='Content-Type', requote=True, charset=None, language='')`229230Устанавливает параметр в заголовке *Content-Type*. Если параметр уже существует в заголовке, его значение будет заменено на *value*. Если заголовок *Content-Type* ещё не задан для этого сообщения, он будет установлен в *text/plain*, а новое значение параметра будет добавлено в соответствии с [**RFC 2045**](https://python-all.ru/3.3/library/email.message.html).231232Необязательный параметр *header* указывает альтернативный заголовок для *Content-Type*, и все параметры будут заключаться в кавычки по мере необходимости, если необязательный параметр *requote* не равен `False` (по умолчанию `True`).233234Если указан необязательный параметр *charset*, параметр будет закодирован в соответствии с [**RFC 2231**](https://python-all.ru/3.3/library/email.message.html). Необязательный параметр *language* задаёт язык по RFC 2231, по умолчанию – пустая строка. И *charset*, и *language* должны быть строками.235236#### `del_param(param, header='content-type', requote=True)`237238Полностью удаляет указанный параметр из заголовка *Content-Type*. Заголовок перезаписывается на месте без параметра и его значения. Все значения заключаются в кавычки по необходимости, если только *requote* не равен `False` (по умолчанию `True`). Необязательный *header* задаёт альтернативу *Content-Type*.239240#### `set_type(type, header='Content-Type', requote=True)`241242Устанавливает основной тип и подтип для заголовка *Content-Type*. *type* должен быть строкой вида *maintype/subtype*, иначе вызывается [`ValueError`](https://python-all.ru/3.3/library/exceptions.html#ValueError).243244Этот метод заменяет заголовок *Content-Type*, сохраняя все параметры на месте. Если *requote* равен `False`, то существующие кавычки в заголовке остаются без изменений; в противном случае параметры заключаются в кавычки (по умолчанию).245246Альтернативный заголовок можно указать в аргументе *header*. При установке заголовка *Content-Type* также добавляется заголовок *MIME-Version*.247248#### `get_filename(failobj=None)`249250Возвращает значение параметра `filename` заголовка *Content-Disposition* сообщения. Если заголовок не содержит параметра `filename`, метод ищет параметр `name` в заголовке *Content-Type*. Если не найден ни один из них или заголовок отсутствует, возвращается *failobj*. Возвращаемая строка всегда лишается кавычек в соответствии с [`email.utils.unquote()`](https://python-all.ru/3.3/library/email.util.html#email.utils.unquote).251252#### `get_boundary(failobj=None)`253254Возвращает значение параметра `boundary` заголовка *Content-Type* сообщения или *failobj*, если либо заголовок отсутствует, либо не имеет параметра `boundary`. Возвращаемая строка всегда лишается кавычек в соответствии с [`email.utils.unquote()`](https://python-all.ru/3.3/library/email.util.html#email.utils.unquote).255256#### `set_boundary(boundary)`257258Устанавливает параметр `boundary` заголовка *Content-Type* в *boundary*. [`set_boundary()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.set_boundary) всегда заключает *boundary* в кавычки при необходимости. Исключение [`HeaderParseError`](https://python-all.ru/3.3/library/email.errors.html#email.errors.HeaderParseError) вызывается, если у объекта сообщения нет заголовка *Content-Type*.259260Обратите внимание, что использование этого метода незначительно отличается от удаления старого заголовка *Content-Type* и добавления нового с новым разделителем через [`add_header()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.add_header), потому что [`set_boundary()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.set_boundary) сохраняет порядок заголовка *Content-Type* в списке заголовков. Однако он *не* сохраняет никакие строки продолжения, которые могли присутствовать в исходном заголовке *Content-Type*.261262#### `get_content_charset(failobj=None)`263264Возвращает параметр `charset` заголовка *Content-Type*, приведённый к нижнему регистру. Если заголовка *Content-Type* нет или в нём отсутствует параметр `charset`, возвращается *failobj*.265266Обратите внимание, что этот метод отличается от [`get_charset()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.get_charset), который возвращает экземпляр [`Charset`](https://python-all.ru/3.3/library/email.charset.html#email.charset.Charset) для кодировки по умолчанию тела сообщения.267268#### `get_charsets(failobj=None)`269270Возвращает список, содержащий имена наборов символов в сообщении. Если сообщение является *multipart*, список будет содержать по одному элементу для каждой вложенной части в полезной нагрузке; в противном случае это будет список длиной 1.271272Каждый элемент списка будет строкой, которая является значением параметра `charset` в заголовке *Content-Type* для представленной подчасти. Однако если подчасть не имеет заголовка *Content-Type*, не имеет параметра `charset` или не является *text* основным MIME-типом, то этот элемент в возвращаемом списке будет равен *failobj*.273274#### `walk()`275276Метод [`walk()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.walk) – это универсальный генератор, который можно использовать для перебора всех частей и подчастей дерева объектов сообщения в порядке обхода в глубину. Обычно [`walk()`](https://python-all.ru/3.3/library/email.message.html#email.message.Message.walk) применяется как итератор в цикле `for`; каждая итерация возвращает следующую подчасть.277278Вот пример, который выводит MIME-тип каждой части многокомпонентной структуры сообщения:279280> ```python281> >>> for part in msg.walk():282> ... print(part.get_content_type())283> multipart/report284> text/plain285> message/delivery-status286> text/plain287> text/plain288> message/rfc822289> text/plain290> ```291292Объекты [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message) также могут опционально содержать два атрибута экземпляра, которые можно использовать при создании обычного текста MIME-сообщения.293294#### `preamble`295296Формат MIME-документа допускает наличие некоторого текста между пустой строкой после заголовков и первой строкой границы multipart. Обычно этот текст не виден в MIME-совместимом почтовом клиенте, поскольку он находится вне стандартной MIME-защиты. Однако при просмотре необработанного текста сообщения или при просмотре сообщения в клиенте, не поддерживающем MIME, этот текст может стать видимым.297298Атрибут *preamble* содержит этот начальный дополнительный текст для MIME-документов. Когда [`Parser`](https://python-all.ru/3.3/library/email.parser.html#email.parser.Parser) обнаруживает некоторый текст после заголовков, но перед первой строкой границы, он присваивает этот текст атрибуту *preamble* сообщения. Когда [`Generator`](https://python-all.ru/3.3/library/email.generator.html#email.generator.Generator) записывает текстовое представление MIME-сообщения и находит, что у сообщения есть атрибут *preamble*, он записывает этот текст в область между заголовками и первой границей. Подробнее см. [`email.parser`](https://python-all.ru/3.3/library/email.parser.html#module-email.parser) и [`email.generator`](https://python-all.ru/3.3/library/email.generator.html#module-email.generator).299300Обратите внимание: если объект сообщения не имеет преамбулы, атрибут *preamble* будет равен `None`.301302#### `epilogue`303304Атрибут *epilogue* действует так же, как атрибут *preamble*, за исключением того, что он содержит текст, который появляется между последней границей и концом сообщения.305306Вам не нужно задавать эпилог пустой строкой, чтобы [`Generator`](https://python-all.ru/3.3/library/email.generator.html#email.generator.Generator) выводил символ новой строки в конце файла.307308#### `defects`309310Атрибут *defects* содержит список всех проблем, обнаруженных при разборе этого сообщения. Подробное описание возможных дефектов разбора см. в [`email.errors`](https://python-all.ru/3.3/library/email.errors.html#module-email.errors).311