Документация Python неофициальный перевод

email.compat32-message.md

397 строк · 51.5 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.15/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.15/library/email.compat32-message.html#email.message.Message): представление email-сообщения с помощью API [`compat32`](https://python-all.ru/3.15/library/email.policy.html#email.policy.compat32)89Класс [`Message`](https://python-all.ru/3.15/library/email.compat32-message.html#email.message.Message) очень похож на класс [`EmailMessage`](https://python-all.ru/3.15/library/email.message.html#email.message.EmailMessage), но без методов, добавленных в этом классе, и с немного отличающимся поведением по умолчанию некоторых других методов. Здесь также описаны методы, которые, хотя и поддерживаются классом `EmailMessage`, не рекомендуются к использованию, кроме случаев работы с устаревшим кодом.1011В остальном философия и структура обоих классов одинаковы.1213В этом документе описывается поведение при использовании политики [`Compat32`](https://python-all.ru/3.15/library/email.policy.html#email.policy.Compat32) по умолчанию (для [`Message`](https://python-all.ru/3.15/library/email.compat32-message.html#email.message.Message)). При использовании другой политики следует использовать класс [`EmailMessage`](https://python-all.ru/3.15/library/email.message.html#email.message.EmailMessage).1415An email message consists of *headers* and a *payload*. Headers must be [**RFC 5322**](https://python-all.ru/3.15/library/email.compat32-message.html) style 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*.1617Концептуальная модель объекта [`Message`](https://python-all.ru/3.15/library/email.compat32-message.html#email.message.Message) представляет собой упорядоченный словарь заголовков с дополнительными методами для доступа как к специализированной информации из заголовков, так и к полезной нагрузке, для генерации сериализованной версии сообщения и для рекурсивного обхода дерева объектов. Обратите внимание, что дублирующиеся заголовки поддерживаются, но для доступа к ним необходимо использовать специальные методы.1819Псевдословарь [`Message`](https://python-all.ru/3.15/library/email.compat32-message.html#email.message.Message) индексируется по именам заголовков, которые должны быть значениями ASCII. Значения словаря – строки, которые должны содержать только символы ASCII; предусмотрена специальная обработка для входных данных, не являющихся ASCII, но она не всегда дает правильные результаты. Заголовки хранятся и возвращаются с сохранением регистра, но имена полей сопоставляются без учета регистра. Также может присутствовать единичный конвертный заголовок, также известный как заголовок *Unix-From* или заголовок `From_`. *Полезная нагрузка* представляет собой либо строку, либо байты в случае простых объектов сообщений, либо список объектов `Message` для документов-контейнеров MIME (например, *multipart/\** и *message/rfc822*).2021Ниже приведены методы класса [`Message`](https://python-all.ru/3.15/library/email.compat32-message.html#email.message.Message):2223#### `class email.message.Message(policy=compat32)`2425Если указан параметр *policy* (он должен быть экземпляром класса [`policy`](https://python-all.ru/3.15/library/email.policy.html#module-email.policy)), используйте заданные им правила для обновления и сериализации представления сообщения. Если *policy* не задан, используется политика [`compat32`](https://python-all.ru/3.15/library/email.policy.html#email.policy.Compat32), которая обеспечивает обратную совместимость с версией Python 3.2 пакета 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`, если необходимо заполнить значения по умолчанию для завершения преобразования в строку (например, могут быть созданы или изменены MIME-границы).3435Обратите внимание, что этот метод предоставляется для удобства и не всегда форматирует сообщение так, как требуется. Например, по умолчанию он не выполняет преобразование строк, начинающихся с `From`, которое требуется для формата Unix mbox. Для большей гибкости создайте экземпляр [`Generator`](https://python-all.ru/3.15/library/email.generator.html#email.generator.Generator) и используйте его метод [`flatten()`](https://python-all.ru/3.15/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.15/library/email.compat32-message.html#email.message.Message.as_bytes) и [`BytesGenerator`](https://python-all.ru/3.15/library/email.generator.html#email.generator.BytesGenerator).)4748Изменено в версии 3.4: Добавлен именованный аргумент *policy*.4950#### `__str__()`5152Эквивалентно [`as_string()`](https://python-all.ru/3.15/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`, если необходимо заполнить значения по умолчанию для завершения преобразования в строку (например, могут быть созданы или изменены MIME-границы).5960Обратите внимание, что этот метод предоставляется для удобства и не всегда форматирует сообщение так, как требуется. Например, по умолчанию он не выполняет преобразование строк, начинающихся с `From`, которое требуется для формата Unix mbox. Для большей гибкости создайте экземпляр [`BytesGenerator`](https://python-all.ru/3.15/library/email.generator.html#email.generator.BytesGenerator) и используйте его метод [`flatten()`](https://python-all.ru/3.15/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.15/library/email.compat32-message.html#email.message.Message.as_bytes). Позволяет `bytes(msg)` создавать объект bytes, содержащий отформатированное сообщение.7677Добавлено в версии 3.4.7879#### `is_multipart()`8081Возвращает `True`, если полезная нагрузка сообщения является списком объектов `Message`, иначе возвращает `False`. Когда `is_multipart()` возвращает `False`, полезная нагрузка должна быть строковым объектом (который может быть двоичной полезной нагрузкой, закодированной с помощью CTE). (Обратите внимание, что возврат `True` методом `is_multipart()` не обязательно означает, что «msg.get\_content\_maintype() == 'multipart'» вернёт `True`. Например, `is_multipart` вернёт `True`, когда `Message` имеет тип `message/rfc822`.)8283#### `set_unixfrom(unixfrom)`8485Устанавливает конвертный заголовок сообщения равным *unixfrom*, который должен быть строкой.8687#### `get_unixfrom()`8889Возвращает конвертный заголовок сообщения. По умолчанию равен `None`, если конвертный заголовок никогда не был установлен.9091#### `attach(payload)`9293Добавляет указанный *payload* к текущему payload, который до вызова должен быть `None` или списком объектов `Message`. После вызова payload всегда будет списком объектов `Message`. Если нужно установить payload в виде скалярного объекта (например, строки), используйте [`set_payload()`](https://python-all.ru/3.15/library/email.compat32-message.html#email.message.Message.set_payload).9495Это устаревший метод. В классе [`EmailMessage`](https://python-all.ru/3.15/library/email.message.html#email.message.EmailMessage) его функциональность заменена методами [`set_content()`](https://python-all.ru/3.15/library/email.message.html#email.message.EmailMessage.set_content), `make` и `add`.9697#### `get_payload(i=None, decode=False)`9899Возвращает текущий payload: список объектов `Message`, если [`is_multipart()`](https://python-all.ru/3.15/library/email.compat32-message.html#email.message.Message.is_multipart) равно `True`, или строку, если `is_multipart()` равно `False`. Если payload является списком и вы изменяете его, вы изменяете payload сообщения на месте.100101С необязательным аргументом *i*, `get_payload()` возвращает *i*-й элемент payload (нумерация с нуля), если [`is_multipart()`](https://python-all.ru/3.15/library/email.compat32-message.html#email.message.Message.is_multipart) равно `True`. Возникает [`IndexError`](https://python-all.ru/3.15/library/exceptions.html#IndexError), если *i* меньше 0 или больше или равно количеству элементов в payload. Если payload является строкой (т.е. `is_multipart()` равно `False`) и передан *i*, возникает [`TypeError`](https://python-all.ru/3.15/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`](https://python-all.ru/3.15/library/email.errors.html#email.errors.InvalidBase64PaddingDefect) или [`InvalidBase64CharactersDefect`](https://python-all.ru/3.15/library/email.errors.html#email.errors.InvalidBase64CharactersDefect) соответственно).104105Когда *decode* равен `False` (по умолчанию), тело возвращается в виде строки без декодирования *Content-Transfer-Encoding*. Однако для *Content-Transfer-Encoding* со значением 8bit предпринимается попытка декодировать исходные байты с использованием `charset`, указанной в заголовке *Content-Type*, с помощью обработчика ошибок `replace`. Если `charset` не указана или указанная `charset` не распознана пакетом email, тело декодируется с использованием кодировки ASCII по умолчанию.106107Это устаревший метод. В классе [`EmailMessage`](https://python-all.ru/3.15/library/email.message.html#email.message.EmailMessage) его функциональность заменена методами [`get_content()`](https://python-all.ru/3.15/library/email.message.html#email.message.EmailMessage.get_content) и [`iter_parts()`](https://python-all.ru/3.15/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.15/library/email.compat32-message.html#email.message.Message.set_charset).112113Это устаревший метод. В классе [`EmailMessage`](https://python-all.ru/3.15/library/email.message.html#email.message.EmailMessage) его функциональность заменена методом [`set_content()`](https://python-all.ru/3.15/library/email.message.html#email.message.EmailMessage.set_content).114115#### `set_charset(charset)`116117Устанавливает кодировку payload в *charset*, который может быть экземпляром [`Charset`](https://python-all.ru/3.15/library/email.charset.html#email.charset.Charset) (см. [`email.charset`](https://python-all.ru/3.15/library/email.charset.html#module-email.charset)), строкой с названием кодировки или `None`. Если это строка, она преобразуется в экземпляр `Charset`. Если *charset* равен `None`, параметр `charset` удаляется из заголовка *Content-Type* (сообщение больше не изменяется). Любое другое значение вызывает [`TypeError`](https://python-all.ru/3.15/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.15/library/email.charset.html#email.charset.Charset), и будет добавлен соответствующий заголовок. Если заголовок *Content-Transfer-Encoding* уже существует, считается, что payload уже корректно закодирован с использованием этого *Content-Transfer-Encoding*, и он не изменяется.120121Это устаревший метод. В классе [`EmailMessage`](https://python-all.ru/3.15/library/email.message.html#email.message.EmailMessage) его функциональность заменена параметром *charset* метода [`email.message.EmailMessage.set_content()`](https://python-all.ru/3.15/library/email.message.html#email.message.EmailMessage.set_content).122123#### `get_charset()`124125Возвращает экземпляр [`Charset`](https://python-all.ru/3.15/library/email.charset.html#email.charset.Charset), связанный с payload сообщения.126127Это устаревший метод. В классе [`EmailMessage`](https://python-all.ru/3.15/library/email.message.html#email.message.EmailMessage) он всегда возвращает `None`.128129Следующие методы реализуют интерфейс, похожий на словарь, для доступа к заголовкам сообщения в формате [**RFC 2822**](https://python-all.ru/3.15/library/email.compat32-message.html). Обратите внимание на некоторые семантические отличия от обычного словаря. Например, в словаре нет дублирующихся ключей, а здесь могут быть повторяющиеся заголовки. Также в словарях нет гарантированного порядка ключей, возвращаемых [`keys()`](https://python-all.ru/3.15/library/email.compat32-message.html#email.message.Message.keys), а в объекте `Message` заголовки всегда возвращаются в том порядке, в котором они встречались в исходном сообщении или были добавлены позже. Любой удалённый и затем повторно добавленный заголовок всегда добавляется в конец списка заголовков.130131Эти семантические различия являются намеренными и направлены на максимальное удобство.132133Обратите внимание, что во всех случаях заголовки конверта, присутствующие в сообщении, не включаются в интерфейс отображения.134135В модели, созданной из байтов, любые значения заголовков, которые (вопреки RFC) содержат не-ASCII байты, при получении через этот интерфейс будут представлены как объекты [`Header`](https://python-all.ru/3.15/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.15/library/exceptions.html#KeyError) никогда не возбуждается.153154Обратите внимание: если указанное поле встречается в заголовках сообщения более одного раза, то не определено, какое именно из этих значений будет возвращено. Используйте метод [`get_all()`](https://python-all.ru/3.15/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.15/reference/datamodel.html#object.__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.15/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.15/library/email.compat32-message.html) для других возможностей), а `VALUE` – строковое значение, содержащее не-ASCII кодовые точки. Если кортеж из трех элементов не передан и значение содержит не-ASCII символы, оно автоматически кодируется в формат [**RFC 2231**](https://python-all.ru/3.15/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.15/library/exceptions.html#KeyError).227228#### `get_content_type()`229230Возвращает тип содержимого сообщения. Возвращаемая строка приводится к нижнему регистру в форме *maintype/subtype*. Если в сообщении не было заголовка *Content-Type*, будет возвращен тип по умолчанию, заданный [`get_default_type()`](https://python-all.ru/3.15/library/email.compat32-message.html#email.message.Message.get_default_type). Поскольку согласно [**RFC 2045**](https://python-all.ru/3.15/library/email.compat32-message.html) сообщения всегда имеют тип по умолчанию, `get_content_type()` всегда возвращает значение.231232[**RFC 2045**](https://python-all.ru/3.15/library/email.compat32-message.html) определяет тип по умолчанию сообщения как *text/plain*, если только оно не находится внутри контейнера *multipart/digest*, в этом случае он будет *message/rfc822*. Если заголовок *Content-Type* содержит недопустимую спецификацию типа, [**RFC 2045**](https://python-all.ru/3.15/library/email.compat32-message.html) предписывает, что типом по умолчанию должен быть *text/plain*.233234#### `get_content_maintype()`235236Возвращает основной тип содержимого сообщения. Это часть *maintype* строки, возвращаемой [`get_content_type()`](https://python-all.ru/3.15/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.15/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.15/library/email.compat32-message.html#email.message.Message.get_param) и не экранируется, если необязательный параметр *unquote* равен `True` (по умолчанию).253254Необязательный параметр *failobj* – объект, возвращаемый при отсутствии заголовка *Content-Type*. Необязательный параметр *header* – заголовок, который нужно искать вместо *Content-Type*.255256Это устаревший метод. В классе [`EmailMessage`](https://python-all.ru/3.15/library/email.message.html#email.message.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.15/library/email.compat32-message.html). Если это кортеж из трёх элементов, элементы значения имеют вид `(CHARSET, LANGUAGE, VALUE)`. Обратите внимание, что и `CHARSET`, и `LANGUAGE` могут быть `None`; в этом случае следует считать, что `VALUE` закодирован в кодировке `us-ascii`. Обычно `LANGUAGE` можно игнорировать.265266Если вашему приложению безразлично, был ли параметр закодирован по [**RFC 2231**](https://python-all.ru/3.15/library/email.compat32-message.html), можно свернуть значение параметра, вызвав [`email.utils.collapse_rfc2231_value()`](https://python-all.ru/3.15/library/email.utils.html#email.utils.collapse_rfc2231_value) и передав возвращаемое значение из `get_param()`. Это вернёт подходящим образом декодированную строку Unicode, если значение является кортежем, или исходную строку без кавычек, если нет. Например:267268```python269rawparam = msg.get_param('foo')270param = email.utils.collapse_rfc2231_value(rawparam)271```272273В любом случае значение параметра (возвращённая строка или элемент `VALUE` кортежа из трёх элементов) всегда не экранируется, если только *unquote* не установлен в `False`.274275Это устаревший метод. В классе [`EmailMessage`](https://python-all.ru/3.15/library/email.message.html#email.message.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.15/library/email.compat32-message.html).280281Необязательный параметр *header* задаёт альтернативный заголовок для *Content-Type*; все параметры будут экранированы при необходимости, если только необязательный параметр *requote* не равен `False` (по умолчанию `True`).282283Если указан необязательный параметр *charset*, параметр будет закодирован в соответствии с [**RFC 2231**](https://python-all.ru/3.15/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.15/library/exceptions.html#ValueError).296297Этот метод заменяет заголовок *Content-Type*, сохраняя все параметры на месте. Если *requote* равен `False`, экранирование существующего заголовка остаётся без изменений; в противном случае параметры будут экранированы (по умолчанию).298299Альтернативный заголовок можно указать в аргументе *header*. При установке заголовка *Content-Type* также добавляется заголовок *MIME-Version*.300301Это устаревший метод. В классе [`EmailMessage`](https://python-all.ru/3.15/library/email.message.html#email.message.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.15/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.15/library/email.utils.html#email.utils.unquote).310311#### `set_boundary(boundary)`312313Устанавливает параметр `boundary` заголовка *Content-Type* в значение *boundary*. `set_boundary()` всегда будет заключать *boundary* в кавычки при необходимости. Возбуждается исключение [`HeaderParseError`](https://python-all.ru/3.15/library/email.errors.html#email.errors.HeaderParseError), если объект сообщения не имеет заголовка *Content-Type*.314315Обратите внимание, что использование этого метода незначительно отличается от удаления старого заголовка *Content-Type* и добавления нового с новым boundary через [`add_header()`](https://python-all.ru/3.15/library/email.compat32-message.html#email.message.Message.add_header), поскольку `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.15/library/email.compat32-message.html#email.message.Message.get_charset), который возвращает экземпляр [`Charset`](https://python-all.ru/3.15/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.15/library/email.compat32-message.html).332333Добавлено в версии 3.5.334335#### `walk()`336337Метод `walk()` – это универсальный генератор, который можно использовать для обхода всех частей и подчастей дерева объекта сообщения в порядке прямого обхода в глубину. Обычно `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.15/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` также могут опционально содержать два атрибута экземпляра, которые можно использовать при создании обычного текста MIME-сообщения.379380#### `preamble`381382Формат MIME-документа допускает наличие некоторого текста между пустой строкой после заголовков и первой строкой границы multipart. Обычно этот текст не виден в MIME-совместимом почтовом клиенте, поскольку он находится вне стандартной MIME-защиты. Однако при просмотре необработанного текста сообщения или при просмотре сообщения в клиенте, не поддерживающем MIME, этот текст может стать видимым.383384Атрибут *preamble* содержит этот дополнительный текст за пределами MIME-защиты для MIME-документов. Когда [`Parser`](https://python-all.ru/3.15/library/email.parser.html#email.parser.Parser) обнаруживает некоторый текст после заголовков, но до первой строки границы, он присваивает этот текст атрибуту *preamble* сообщения. Когда [`Generator`](https://python-all.ru/3.15/library/email.generator.html#email.generator.Generator) записывает текстовое представление MIME-сообщения и обнаруживает, что сообщение имеет атрибут *preamble*, он записывает этот текст в области между заголовками и первой границей. Подробнее см. [`email.parser`](https://python-all.ru/3.15/library/email.parser.html#module-email.parser) и [`email.generator`](https://python-all.ru/3.15/library/email.generator.html#module-email.generator).385386Обратите внимание: если у объекта сообщения нет преамбулы, атрибут *preamble* будет равен `None`.387388#### `epilogue`389390Атрибут *epilogue* действует так же, как атрибут *preamble*, за исключением того, что он содержит текст, который появляется между последней границей и концом сообщения.391392Нет необходимости устанавливать epilogue в пустую строку, чтобы [`Generator`](https://python-all.ru/3.15/library/email.generator.html#email.generator.Generator) выводил символ новой строки в конце файла.393394#### `defects`395396Атрибут *defects* содержит список всех проблем, обнаруженных при разборе этого сообщения. См. [`email.errors`](https://python-all.ru/3.15/library/email.errors.html#module-email.errors) для подробного описания возможных дефектов разбора.397