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

email.generator.md

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

1> **Источник:** https://python-all.ru/3.10/library/email.generator.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [`email.generator`](https://python-all.ru/3.10/library/email.generator.html#module-email.generator): Генерация MIME-документов89**Исходный код:** [Lib/email/generator.py](https://python-all.ru/src/3.10/Lib/email/generator.py)1011---1213Одна из самых распространённых задач – создание плоской (сериализованной) версии email-сообщения, представленного структурой объекта сообщения. Это понадобится, если нужно отправить сообщение через [`smtplib.SMTP.sendmail()`](https://python-all.ru/3.10/library/smtplib.html#smtplib.SMTP.sendmail) или модуль [`nntplib`](https://python-all.ru/3.10/library/nntplib.html#module-nntplib), или вывести сообщение на консоль. За создание сериализованного представления из структуры объекта сообщения отвечают классы генераторов.1415Как и в случае с модулем [`email.parser`](https://python-all.ru/3.10/library/email.parser.html#module-email.parser), функциональность не ограничена встроенным генератором; можно написать свой с нуля. Однако встроенный генератор умеет создавать большинство писем в соответствии со стандартами, корректно обрабатывает как MIME-, так и не-MIME-сообщения и спроектирован так, что байт-ориентированные операции разбора и генерации являются обратными друг другу при условии использования одного и того же нетрансформирующего [`policy`](https://python-all.ru/3.10/library/email.policy.html#module-email.policy) для обеих. То есть, разбор сериализованного байтового потока через класс [`BytesParser`](https://python-all.ru/3.10/library/email.parser.html#email.parser.BytesParser) и последующая генерация сериализованного байтового потока с помощью [`BytesGenerator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.BytesGenerator) должны давать вывод, идентичный входному [1](https://python-all.ru/3.10/library/email.generator.html#id3). (С другой стороны, использование генератора на объекте [`EmailMessage`](https://python-all.ru/3.10/library/email.message.html#email.message.EmailMessage), созданном программно, может привести к изменениям объекта [`EmailMessage`](https://python-all.ru/3.10/library/email.message.html#email.message.EmailMessage), так как заполняются значения по умолчанию.)1617Класс [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator) можно использовать для преобразования сообщения в текстовое (в отличие от двоичного) сериализованное представление, но поскольку Unicode не может напрямую представлять двоичные данные, сообщение неизбежно преобразуется в нечто, содержащее только символы ASCII, с использованием стандартных методов кодирования пересылки содержимого согласно RFC электронной почты для передачи по каналам, которые не являются «8-битно чистыми».1819Для обеспечения воспроизводимой обработки SMIME-подписанных сообщений [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator) отключает сворачивание заголовков для частей сообщения типа `multipart/signed` и всех подчастей.2021#### `class email.generator.BytesGenerator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)`2223Возвращает объект [`BytesGenerator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.BytesGenerator), который будет записывать любое сообщение, переданное методу [`flatten()`](https://python-all.ru/3.10/library/email.generator.html#email.generator.BytesGenerator.flatten), или любой текст, закодированный с surrogateescape, переданный методу [`write()`](https://python-all.ru/3.10/library/email.generator.html#email.generator.BytesGenerator.write), в [объект, подобный файлу](https://python-all.ru/3.10/glossary.html#term-file-like-object) *outfp*. *outfp* должен поддерживать метод `write`, принимающий двоичные данные.2425Если необязательный параметр *mangle\_from\_* равен `True`, перед каждой строкой тела, начинающейся с точной строки `"From "`, то есть `From` с пробелом в начале строки, ставится символ `>`. *mangle\_from\_* по умолчанию равен значению настройки [`mangle_from_`](https://python-all.ru/3.10/library/email.policy.html#email.policy.Policy.mangle_from_) политики *policy* (которое равно `True` для политики [`compat32`](https://python-all.ru/3.10/library/email.policy.html#email.policy.compat32) и `False` для всех остальных). *mangle\_from\_* предназначен для использования, когда сообщения хранятся в формате Unix mbox (см. [`mailbox`](https://python-all.ru/3.10/library/mailbox.html#module-mailbox) и [ПОЧЕМУ ФОРМАТ CONTENT-LENGTH ПЛОХ](https://python-all.ru/3.10/library/email.generator.html)).2627Если *maxheaderlen* не равен `None`, переформатировать любые строки заголовков, длиннее *maxheaderlen*, а если `0`, не переносить заголовки. Если *manheaderlen* равен `None` (по умолчанию), переносить заголовки и другие строки сообщения в соответствии с настройками *policy*.2829Если указан *policy*, использовать эту политику для управления генерацией сообщений. Если *policy* равен `None` (по умолчанию), использовать политику, связанную с объектом [`Message`](https://python-all.ru/3.10/library/email.compat32-message.html#email.message.Message) или [`EmailMessage`](https://python-all.ru/3.10/library/email.message.html#email.message.EmailMessage), переданным в `flatten`, для управления генерацией сообщений. Подробнее о том, что контролирует *policy*, см. в [`email.policy`](https://python-all.ru/3.10/library/email.policy.html#module-email.policy).3031Новое в версии 3.2.3233Изменено в версии 3.3: Добавлен параметр *policy*.3435Изменено в версии 3.6: Поведение по умолчанию параметров *mangle\_from\_* и *maxheaderlen* теперь следует политике.3637#### `flatten(msg, unixfrom=False, linesep=None)`3839Выводит текстовое представление структуры объекта сообщения, корнем которой является *msg*, в выходной файл, указанный при создании экземпляра [`BytesGenerator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.BytesGenerator).4041Если опция [`policy`](https://python-all.ru/3.10/library/email.policy.html#module-email.policy) [`cte_type`](https://python-all.ru/3.10/library/email.policy.html#email.policy.Policy.cte_type) равна `8bit` (по умолчанию), копировать все заголовки в исходном разобранном сообщении, которые не были изменены, в вывод, воспроизводя любые байты с установленным старшим битом как в оригинале, и сохранять не-ASCII *Content-Transfer-Encoding* любых частей тела, имеющих его. Если `cte_type` равен `7bit`, преобразовывать байты с установленным старшим битом по мере необходимости, используя совместимый с ASCII *Content-Transfer-Encoding*. То есть, преобразовывать части с не-ASCII *Content-Transfer-Encoding* (*Content-Transfer-Encoding: 8bit*) в совместимый с ASCII *Content-Transfer-Encoding*, и кодировать недопустимые по RFC не-ASCII байты в заголовках, используя набор символов MIME `unknown-8bit`, делая их таким образом соответствующими RFC.4243Если *unixfrom* равно `True`, печатать разделитель заголовка конверта, используемый форматом почтовых ящиков Unix (см. [`mailbox`](https://python-all.ru/3.10/library/mailbox.html#module-mailbox)), перед первым из заголовков [**RFC 5322**](https://python-all.ru/3.10/library/email.generator.html) корневого объекта сообщения. Если корневой объект не имеет заголовка конверта, сформировать стандартный. По умолчанию `False`. Обратите внимание, что для подчастей заголовок конверта никогда не печатается.4445Если *linesep* не равно `None`, использовать его как символ-разделитель между всеми строками сериализованного сообщения. Если *linesep* равно `None` (по умолчанию), использовать значение, указанное в *policy*.4647#### `clone(fp)`4849Возвращает независимую копию этого экземпляра [`BytesGenerator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.BytesGenerator) с точно такими же настройками параметров и *fp* в качестве нового *outfp*.5051#### `write(s)`5253Кодирует *s*, используя кодек `ASCII` и обработчик ошибок `surrogateescape`, и передаёт его методу *write* объекта *outfp*, переданного конструктору [`BytesGenerator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.BytesGenerator).5455Для удобства [`EmailMessage`](https://python-all.ru/3.10/library/email.message.html#email.message.EmailMessage) предоставляет методы [`as_bytes()`](https://python-all.ru/3.10/library/email.message.html#email.message.EmailMessage.as_bytes) и `bytes(aMessage)` (также известный как [`__bytes__()`](https://python-all.ru/3.10/library/email.message.html#email.message.EmailMessage.__bytes__)), которые упрощают генерацию сериализованного двоичного представления объекта сообщения. Подробнее см. [`email.message`](https://python-all.ru/3.10/library/email.message.html#module-email.message).5657Поскольку строки не могут представлять двоичные данные, класс [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator) должен преобразовывать любые двоичные данные в любом сообщении, которое он формирует, в формат, совместимый с ASCII, преобразуя их в совместимое с ASCII *Content-Transfer-Encoding*. Используя терминологию RFC электронной почты, это можно рассматривать как сериализацию [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator) в поток I/O, который не является «8-битно чистым». Другими словами, большинству приложений следует использовать [`BytesGenerator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.BytesGenerator), а не [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator).5859#### `class email.generator.Generator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)`6061Возвращает объект [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator), который будет записывать любое сообщение, переданное методу [`flatten()`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator.flatten), или любой текст, переданный методу [`write()`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator.write), в [объект, подобный файлу](https://python-all.ru/3.10/glossary.html#term-file-like-object) *outfp*. *outfp* должен поддерживать метод `write`, принимающий строковые данные.6263Если необязательный параметр *mangle\_from\_* равен `True`, перед каждой строкой тела, начинающейся с точной строки `"From "`, то есть `From` с пробелом в начале строки, ставится символ `>`. *mangle\_from\_* по умолчанию равен значению настройки [`mangle_from_`](https://python-all.ru/3.10/library/email.policy.html#email.policy.Policy.mangle_from_) политики *policy* (которое равно `True` для политики [`compat32`](https://python-all.ru/3.10/library/email.policy.html#email.policy.compat32) и `False` для всех остальных). *mangle\_from\_* предназначен для использования, когда сообщения хранятся в формате Unix mbox (см. [`mailbox`](https://python-all.ru/3.10/library/mailbox.html#module-mailbox) и [ПОЧЕМУ ФОРМАТ CONTENT-LENGTH ПЛОХ](https://python-all.ru/3.10/library/email.generator.html)).6465Если *maxheaderlen* не равен `None`, переформатировать любые строки заголовков, длиннее *maxheaderlen*, а если `0`, не переносить заголовки. Если *manheaderlen* равен `None` (по умолчанию), переносить заголовки и другие строки сообщения в соответствии с настройками *policy*.6667Если указан *policy*, использовать эту политику для управления генерацией сообщений. Если *policy* равен `None` (по умолчанию), использовать политику, связанную с объектом [`Message`](https://python-all.ru/3.10/library/email.compat32-message.html#email.message.Message) или [`EmailMessage`](https://python-all.ru/3.10/library/email.message.html#email.message.EmailMessage), переданным в `flatten`, для управления генерацией сообщений. Подробнее о том, что контролирует *policy*, см. в [`email.policy`](https://python-all.ru/3.10/library/email.policy.html#module-email.policy).6869Изменено в версии 3.3: Добавлен параметр *policy*.7071Изменено в версии 3.6: Поведение по умолчанию параметров *mangle\_from\_* и *maxheaderlen* теперь следует политике.7273#### `flatten(msg, unixfrom=False, linesep=None)`7475Выводит текстовое представление структуры объекта сообщения, корнем которой является *msg*, в выходной файл, указанный при создании экземпляра [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator).7677Если опция [`policy`](https://python-all.ru/3.10/library/email.policy.html#module-email.policy) [`cte_type`](https://python-all.ru/3.10/library/email.policy.html#email.policy.Policy.cte_type) равна `8bit`, генерировать сообщение так, как если бы опция была установлена в `7bit`. (Это необходимо, потому что строки не могут представлять не-ASCII байты.) Преобразовывать любые байты с установленным старшим битом по необходимости, используя совместимую с ASCII *Content-Transfer-Encoding*. То есть преобразовывать части с не-ASCII *Content-Transfer-Encoding* (*Content-Transfer-Encoding: 8bit*) в совместимую с ASCII *Content-Transfer-Encoding*, и кодировать не соответствующие RFC не-ASCII байты в заголовках, используя набор символов MIME `unknown-8bit`, тем самым делая их соответствующими RFC.7879Если *unixfrom* равно `True`, печатать разделитель заголовка конверта, используемый форматом почтовых ящиков Unix (см. [`mailbox`](https://python-all.ru/3.10/library/mailbox.html#module-mailbox)), перед первым из заголовков [**RFC 5322**](https://python-all.ru/3.10/library/email.generator.html) корневого объекта сообщения. Если корневой объект не имеет заголовка конверта, сформировать стандартный. По умолчанию `False`. Обратите внимание, что для подчастей заголовок конверта никогда не печатается.8081Если *linesep* не равно `None`, использовать его как символ-разделитель между всеми строками сериализованного сообщения. Если *linesep* равно `None` (по умолчанию), использовать значение, указанное в *policy*.8283Изменено в версии 3.2: Добавлена поддержка перекодировки тел сообщений `8bit` и аргумента *linesep*.8485#### `clone(fp)`8687Возвращает независимый клон экземпляра [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator) с теми же параметрами и *fp* в качестве нового *outfp*.8889#### `write(s)`9091Записывает *s* в метод *write* объекта *outfp*, переданного в конструктор [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator). Этого достаточно для использования экземпляров [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator) в функции [`print()`](https://python-all.ru/3.10/library/functions.html#print) в качестве файлоподобного API.9293Для удобства [`EmailMessage`](https://python-all.ru/3.10/library/email.message.html#email.message.EmailMessage) предоставляет методы [`as_string()`](https://python-all.ru/3.10/library/email.message.html#email.message.EmailMessage.as_string) и `str(aMessage)` (также известный как [`__str__()`](https://python-all.ru/3.10/library/email.message.html#email.message.EmailMessage.__str__)), которые упрощают создание форматированного строкового представления объекта сообщения. Подробнее см. [`email.message`](https://python-all.ru/3.10/library/email.message.html#module-email.message).9495Модуль [`email.generator`](https://python-all.ru/3.10/library/email.generator.html#module-email.generator) также предоставляет производный класс [`DecodedGenerator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.DecodedGenerator), который похож на базовый класс [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator), за исключением того, что части не типа *text* не сериализуются, а вместо этого представляются в выходном потоке строкой, полученной из шаблона, заполненного информацией о части.9697#### `class email.generator.DecodedGenerator(outfp, mangle_from_=None, maxheaderlen=None, fmt=None, *, policy=None)`9899Работает как [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator), за исключением того, что для любой подчасти сообщения, переданной в [`Generator.flatten()`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator.flatten), если подчасть имеет основной тип *text*, выводится декодированное содержимое подчасти, а если основной тип не *text*, то вместо вывода заполняется строка *fmt* с использованием информации из части и выводится полученная заполненная строка.100101Чтобы заполнить *fmt*, выполните `fmt % part_info`, где `part_info` – это словарь, состоящий из следующих ключей и значений:102103- `type` – полный MIME-тип части не-*text*104- `maintype` – основной MIME-тип части не-*text*105- `subtype` – подтип MIME части не-*text*106- `filename` – имя файла части не-*text*107- `description` – описание, связанное с частью не-*text*108- `encoding` – кодировка передачи содержимого части не-*text*109110Если *fmt* равно `None`, используйте следующий *fmt* по умолчанию:111112> “\[Часть сообщения не текстового типа (%(type)s) пропущена, имя файла %(filename)s\]”113114Необязательные *\_mangle\_from\_* и *maxheaderlen* такие же, как в базовом классе [`Generator`](https://python-all.ru/3.10/library/email.generator.html#email.generator.Generator).115116Сноски117118**[1](https://python-all.ru/3.10/library/email.generator.html#id1)**119120Данное утверждение предполагает, что используются соответствующие настройки для `unixfrom` и что нет настроек `policy`, требующих автоматической корректировки (например, `refold_source` должно быть `none`, что *не* является значением по умолчанию). Это также не совсем верно, поскольку если сообщение не соответствует стандартам RFC, иногда информация о точном исходном тексте теряется при восстановлении после ошибок синтаксического разбора. Цель – исправить эти последние крайние случаи, когда это возможно.121