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

email.generator.md

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

1> **Источник:** https://python-all.ru/3.5/library/email.generator.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 19.1.3. [`email.generator`](https://python-all.ru/3.5/library/email.generator.html#module-email.generator): Генерация MIME-документов89**Исходный код:** [Lib/email/generator.py](https://python-all.ru/src/3.5/Lib/email/generator.py)1011---1213Одна из самых распространённых задач – сгенерировать плоский текст email-сообщения, представленного структурой объекта сообщения. Это понадобится, чтобы отправить сообщение через модуль [`smtplib`](https://python-all.ru/3.5/library/smtplib.html#module-smtplib) или модуль [`nntplib`](https://python-all.ru/3.5/library/nntplib.html#module-nntplib), либо вывести сообщение на консоль. Преобразование структуры объекта сообщения в плоский текст – задача класса [`Generator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.Generator).1415Как и в случае с модулем [`email.parser`](https://python-all.ru/3.5/library/email.parser.html#module-email.parser), вы не ограничены функциональностью встроенного генератора; можете написать свой с нуля. Однако встроенный генератор умеет генерировать большинство email-сообщений в соответствии со стандартами, корректно обрабатывает MIME и не-MIME сообщения и спроектирован так, что преобразование из плоского текста в структуру сообщения через класс [`Parser`](https://python-all.ru/3.5/library/email.parser.html#email.parser.Parser) и обратно в плоский текст является идемпотентным (вход идентичен выходу) [\[1\]](https://python-all.ru/3.5/library/email.generator.html#id3). С другой стороны, использование Generator для [`Message`](https://python-all.ru/3.5/library/email.message.html#email.message.Message), созданного программно, может привести к изменениям объекта [`Message`](https://python-all.ru/3.5/library/email.message.html#email.message.Message), так как заполняются значения по умолчанию.1617Вывод [`bytes`](https://python-all.ru/3.5/library/functions.html#bytes) можно сгенерировать с помощью класса [`BytesGenerator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.BytesGenerator). Если структура объекта сообщения содержит не-ASCII байты, метод [`flatten()`](https://python-all.ru/3.5/library/email.generator.html#email.generator.BytesGenerator.flatten) этого генератора выдаст исходные байты. Разбор двоичного сообщения и последующее преобразование в плоский текст с помощью [`BytesGenerator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.BytesGenerator) должно быть идемпотентным для сообщений, соответствующих стандартам.1819Вот открытые методы класса [`Generator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.Generator), импортируемые из модуля [`email.generator`](https://python-all.ru/3.5/library/email.generator.html#module-email.generator):2021#### `class email.generator.Generator(outfp, mangle_from_=True, maxheaderlen=78, *, policy=None)`2223Конструктор класса [`Generator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.Generator) принимает [объект, подобный файлу](https://python-all.ru/3.5/glossary.html#term-file-like-object), называемый *outfp*, в качестве аргумента. *outfp* должен поддерживать метод [`write()`](https://python-all.ru/3.5/library/email.generator.html#email.generator.Generator.write) и может использоваться как выходной файл для функции [`print()`](https://python-all.ru/3.5/library/functions.html#print).2425Необязательный флаг *mangle\_from\_* – это флаг, который при значении `True` помещает символ `>` перед любой строкой в теле, которая начинается точно с `From`, т.е. `From` с последующим пробелом в начале строки. Это единственный гарантированно переносимый способ избежать ошибочного восприятия таких строк как разделителя заголовка конверта формата Unix mailbox (см. [WHY THE CONTENT-LENGTH FORMAT IS BAD](https://python-all.ru/3.5/library/email.generator.html) для подробностей). *mangle\_from\_* по умолчанию равен `True`, но вы можете захотеть установить его в `False`, если не записываете файлы в формате Unix mailbox.2627Необязательный параметр *maxheaderlen* задаёт максимальную длину для непродолжающегося заголовка. Если строка заголовка длиннее *maxheaderlen* (в символах, табуляция раскрывается до 8 пробелов), заголовок будет разбит, как определено в классе [`Header`](https://python-all.ru/3.5/library/email.header.html#email.header.Header). Установите 0, чтобы отключить перенос заголовков. Значение по умолчанию – 78, как рекомендуется (но не требуется) в [**RFC 2822**](https://python-all.ru/3.5/library/email.generator.html).2829Ключевое слово *policy* задаёт объект [`policy`](https://python-all.ru/3.5/library/email.policy.html#module-email.policy), управляющий рядом аспектов работы генератора. Если *policy* не указан, то используется *policy*, прикреплённый к объекту сообщения, переданному в [`flatten`](https://python-all.ru/3.5/library/email.generator.html#email.generator.Generator.flatten).3031Изменено в версии 3.3: Добавлен параметр *policy*.3233Другие открытые методы [`Generator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.Generator):3435#### `flatten(msg, unixfrom=False, linesep=None)`3637Выводит текстовое представление структуры объекта сообщения, корнем которой является *msg*, в выходной файл, указанный при создании экземпляра [`Generator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.Generator). Подчасти обходятся в глубину, и результирующий текст будет корректно закодирован в MIME.3839Необязательный флаг *unixfrom* принудительно выводит разделитель заголовка конверта перед первым заголовком [**RFC 2822**](https://python-all.ru/3.5/library/email.generator.html) корневого объекта сообщения. Если у корневого объекта нет заголовка конверта, создаётся стандартный. По умолчанию установлено в `False`, чтобы подавить вывод разделителя конверта.4041Обратите внимание, что для подчастей заголовок конверта никогда не выводится.4243Необязательный параметр *linesep* задаёт символ разделителя строк, используемый для завершения строк в выводе. Если он указан, он переопределяет значение, заданное атрибутом `policy` объекта *msg* или объекта `Generator`.4445Поскольку строки не могут представлять не-ASCII байты, если политика, применяемая при запуске `flatten`, имеет [`cte_type`](https://python-all.ru/3.5/library/email.policy.html#email.policy.Policy.cte_type), установленный в `8bit`, то `Generator` будет работать так, как если бы он был установлен в `7bit`. Это означает, что сообщения, разобранные с помощью Bytes parser, которые имеют *Content-Transfer-Encoding* равное `8bit`, будут преобразованы, чтобы использовать `7bit` Content-Transfer-Encoding. Не-ASCII байты в заголовках будут [**RFC 2047**](https://python-all.ru/3.5/library/email.generator.html) закодированы с кодировкой `unknown-8bit`.4647Изменено в версии 3.2: Добавлена поддержка перекодировки тел сообщений `8bit` и аргумента *linesep*.4849#### `clone(fp)`5051Возвращает независимую копию этого экземпляра [`Generator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.Generator) с теми же параметрами.5253#### `write(s)`5455Записывает строку *s* в базовый файловый объект, т.е. *outfp*, переданный конструктору [`Generator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.Generator). Этого достаточно, чтобы экземпляры [`Generator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.Generator) можно было использовать в функции [`print()`](https://python-all.ru/3.5/library/functions.html#print).5657Для удобства обратитесь к методам [`Message`](https://python-all.ru/3.5/library/email.message.html#email.message.Message): [`as_string()`](https://python-all.ru/3.5/library/email.message.html#email.message.Message.as_string) и `str(aMessage)`, также известным как [`__str__()`](https://python-all.ru/3.5/library/email.message.html#email.message.Message.__str__), которые упрощают генерацию форматированного строкового представления объекта сообщения. Подробнее см. [`email.message`](https://python-all.ru/3.5/library/email.message.html#module-email.message).5859#### `class email.generator.BytesGenerator(outfp, mangle_from_=True, maxheaderlen=78, *, policy=None)`6061Конструктор класса [`BytesGenerator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.BytesGenerator) принимает двоичный [объект, подобный файлу](https://python-all.ru/3.5/glossary.html#term-file-like-object), называемый *outfp*, в качестве аргумента. *outfp* должен поддерживать метод [`write()`](https://python-all.ru/3.5/library/email.generator.html#email.generator.BytesGenerator.write), принимающий двоичные данные.6263Необязательный флаг *mangle\_from\_* – это флаг, который при значении `True` помещает символ `>` перед любой строкой в теле, которая начинается точно с `From`, т.е. `From` с последующим пробелом в начале строки. Это единственный гарантированно переносимый способ избежать ошибочного восприятия таких строк как разделителя заголовка конверта формата Unix mailbox (см. [WHY THE CONTENT-LENGTH FORMAT IS BAD](https://python-all.ru/3.5/library/email.generator.html) для подробностей). *mangle\_from\_* по умолчанию равен `True`, но вы можете захотеть установить его в `False`, если не записываете файлы в формате Unix mailbox.6465Необязательный параметр *maxheaderlen* задаёт максимальную длину для непродолжающегося заголовка. Если строка заголовка длиннее *maxheaderlen* (в символах, табуляция раскрывается до 8 пробелов), заголовок будет разбит, как определено в классе [`Header`](https://python-all.ru/3.5/library/email.header.html#email.header.Header). Установите 0, чтобы отключить перенос заголовков. Значение по умолчанию – 78, как рекомендуется (но не требуется) в [**RFC 2822**](https://python-all.ru/3.5/library/email.generator.html).6667Ключевое слово *policy* задаёт объект [`policy`](https://python-all.ru/3.5/library/email.policy.html#module-email.policy), управляющий рядом аспектов работы генератора. Если *policy* не указан, то используется *policy*, прикреплённый к объекту сообщения, переданному в [`flatten`](https://python-all.ru/3.5/library/email.generator.html#email.generator.BytesGenerator.flatten).6869Изменено в версии 3.3: Добавлен параметр *policy*.7071Другие открытые методы [`BytesGenerator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.BytesGenerator):7273#### `flatten(msg, unixfrom=False, linesep=None)`7475Выводит текстовое представление структуры объекта сообщения, корнем которой является *msg*, в выходной файл, указанный при создании экземпляра [`BytesGenerator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.BytesGenerator). Подчасти обходятся в глубину, и результирующий текст будет корректно закодирован в MIME. Если опция [`policy`](https://python-all.ru/3.5/library/email.policy.html#module-email.policy) [`cte_type`](https://python-all.ru/3.5/library/email.policy.html#email.policy.Policy.cte_type) имеет значение `8bit` (по умолчанию), то любые байты с установленным старшим битом в исходном разобранном сообщении, которые не были изменены, будут скопированы в вывод без изменений. Если `cte_type` равно `7bit`, байты будут преобразованы по мере необходимости с использованием совместимой с ASCII Content-Transfer-Encoding. В частности, не соответствующие RFC не-ASCII байты в заголовках будут закодированы с использованием набора символов MIME `unknown-8bit`, что делает их соответствующими RFC.7677Сообщения, разобранные с помощью Bytes parser, которые имеют *Content-Transfer-Encoding* равный 8bit, будут восстановлены как 8bit, если они не были изменены.7879Необязательный флаг *unixfrom* принудительно выводит разделитель заголовка конверта перед первым заголовком [**RFC 2822**](https://python-all.ru/3.5/library/email.generator.html) корневого объекта сообщения. Если у корневого объекта нет заголовка конверта, создаётся стандартный. По умолчанию установлено в `False`, чтобы подавить вывод разделителя конверта.8081Обратите внимание, что для вложенных частей заголовок конверта никогда не печатается.8283Необязательный *linesep* задаёт символ разделителя строк, используемый для завершения строк в выводе. Если он задан, он переопределяет значение, заданное `Generator` или *msg*'s `policy`.8485#### `clone(fp)`8687Возвращает независимый клон этого экземпляра [`BytesGenerator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.BytesGenerator) с точно такими же параметрами.8889#### `write(s)`9091Записывает строку *s* в нижележащий файловый объект. *s* кодируется с помощью кодека `ASCII` и записывается в метод *write* объекта *outfp* *outfp*, переданного в конструктор [`BytesGenerator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.BytesGenerator). Это предоставляет достаточный файлоподобный API для использования экземпляров [`BytesGenerator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.BytesGenerator) в функции [`print()`](https://python-all.ru/3.5/library/functions.html#print).9293Новое в версии 3.2.9495Модуль [`email.generator`](https://python-all.ru/3.5/library/email.generator.html#module-email.generator) также предоставляет производный класс, называемый [`DecodedGenerator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.DecodedGenerator), который похож на базовый класс [`Generator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.Generator), за исключением того, что не-*text* части заменяются строкой формата, представляющей часть.9697#### `class email.generator.DecodedGenerator(outfp, mangle_from_=True, maxheaderlen=78, fmt=None)`9899Этот класс, производный от [`Generator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.Generator), проходит по всем вложенным частям сообщения. Если вложенная часть имеет основной тип *text*, то выводится декодированная полезная нагрузка этой части. Необязательные параметры *\_mangle\_from\_* и *maxheaderlen* работают так же, как в базовом классе [`Generator`](https://python-all.ru/3.5/library/email.generator.html#email.generator.Generator).100101Если вложенная часть не имеет основного типа *text*, необязательный *fmt* – это строка формата, используемая вместо полезной нагрузки сообщения. *fmt* разворачивается со следующими ключевыми словами в формате `%(keyword)s`:102103- `type` – полный MIME-тип части не-*text*104- `maintype` – основной MIME-тип части не-*text*105- `subtype` – подтип MIME части не-*text*106- `filename` – имя файла части не-*text*107- `description` – описание, связанное с частью не-*text*108- `encoding` – кодировка передачи содержимого части не-*text*109110Значение по умолчанию для *fmt*`None`, то есть111112```python113[Non-text (%(type)s) part of message omitted, filename %(filename)s]114```115116Сноски117118| [\[1\]](https://python-all.ru/3.5/library/email.generator.html#id1) | Это утверждение предполагает использование подходящей настройки для аргумента `unixfrom` и установку maxheaderlen=0 (что сохранит исходную длину строк). Кроме того, это не совсем верно, поскольку во многих случаях серии пробелов в заголовках сворачиваются в одиночные пробелы. Последнее является ошибкой, которая будет исправлена. |119| --- | --- |120