> **Источник:** https://python-all.ru/2.7/library/email.generator.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# 18.1.3. [`email.generator`](https://python-all.ru/2.7/library/email.generator.html#module-email.generator): Генерация MIME-документов

Одна из самых распространённых задач – сгенерировать плоский текст email-сообщения, представленного структурой объекта сообщения. Это понадобится, чтобы отправить сообщение через модуль [`smtplib`](https://python-all.ru/2.7/library/smtplib.html#module-smtplib) или модуль [`nntplib`](https://python-all.ru/2.7/library/nntplib.html#module-nntplib), либо вывести сообщение на консоль. Преобразование структуры объекта сообщения в плоский текст – задача класса [`Generator`](https://python-all.ru/2.7/library/email.generator.html#email.generator.Generator).

Как и в случае с модулем [`email.parser`](https://python-all.ru/2.7/library/email.parser.html#module-email.parser), вы не ограничены функциональностью встроенного генератора; можете написать свой с нуля. Однако встроенный генератор умеет генерировать большинство email-сообщений в соответствии со стандартами, корректно обрабатывает MIME и не-MIME сообщения и спроектирован так, что преобразование из плоского текста в структуру сообщения через класс [`Parser`](https://python-all.ru/2.7/library/email.parser.html#email.parser.Parser) и обратно в плоский текст является идемпотентным (вход идентичен выходу) [1](https://python-all.ru/2.7/library/email.generator.html#id2). С другой стороны, использование Generator для [`Message`](https://python-all.ru/2.7/library/email.message.html#email.message.Message), созданного программно, может привести к изменениям объекта [`Message`](https://python-all.ru/2.7/library/email.message.html#email.message.Message), так как заполняются значения по умолчанию.

Вот открытые методы класса [`Generator`](https://python-all.ru/2.7/library/email.generator.html#email.generator.Generator), импортируемые из модуля [`email.generator`](https://python-all.ru/2.7/library/email.generator.html#module-email.generator):

#### `class email.generator.Generator(outfp[, mangle_from_[, maxheaderlen]])`

Конструктор класса [`Generator`](https://python-all.ru/2.7/library/email.generator.html#email.generator.Generator) принимает файлоподобный объект с именем *outfp* в качестве аргумента. *outfp* должен поддерживать метод [`write()`](https://python-all.ru/2.7/library/email.generator.html#email.generator.Generator.write) и быть пригодным для использования в качестве выходного файла в расширенном операторе print языка Python.

Необязательный флаг *mangle\_from\_* – это флаг, который при значении `True` помещает символ `>` перед любой строкой в теле, которая начинается точно с `From`, т.е. `From` с последующим пробелом в начале строки. Это единственный гарантированно переносимый способ избежать ошибочного восприятия таких строк как разделителя заголовка конверта формата Unix mailbox (см. [WHY THE CONTENT-LENGTH FORMAT IS BAD](https://python-all.ru/2.7/library/email.generator.html) для подробностей). *mangle\_from\_* по умолчанию равен `True`, но вы можете захотеть установить его в `False`, если не записываете файлы в формате Unix mailbox.

Необязательный параметр *maxheaderlen* задаёт максимальную длину для непродолжающегося заголовка. Если строка заголовка длиннее *maxheaderlen* (в символах, табуляция раскрывается до 8 пробелов), заголовок будет разбит, как определено в классе [`Header`](https://python-all.ru/2.7/library/email.header.html#email.header.Header). Установите 0, чтобы отключить перенос заголовков. Значение по умолчанию – 78, как рекомендуется (но не требуется) в [**RFC 2822**](https://python-all.ru/2.7/library/email.generator.html).

Другие открытые методы [`Generator`](https://python-all.ru/2.7/library/email.generator.html#email.generator.Generator):

#### `flatten(msg[, unixfrom])`

Выводит текстовое представление структуры объекта сообщения, корнем которой является *msg*, в выходной файл, указанный при создании экземпляра [`Generator`](https://python-all.ru/2.7/library/email.generator.html#email.generator.Generator). Подчасти обходятся в глубину, и результирующий текст будет корректно закодирован в MIME.

Необязательный флаг *unixfrom* принудительно выводит разделитель заголовка конверта перед первым заголовком [**RFC 2822**](https://python-all.ru/2.7/library/email.generator.html) корневого объекта сообщения. Если у корневого объекта нет заголовка конверта, создаётся стандартный. По умолчанию установлено в `False`, чтобы подавить вывод разделителя конверта.

Обратите внимание, что для вложенных частей заголовок конверта никогда не печатается.

Добавлено в версии 2.2.2.

#### `clone(fp)`

Возвращает независимую копию этого экземпляра [`Generator`](https://python-all.ru/2.7/library/email.generator.html#email.generator.Generator) с теми же параметрами.

Добавлено в версии 2.2.2.

#### `write(s)`

Записывает строку *s* в нижележащий файловый объект, то есть в *outfp*, переданный конструктору [`Generator`](https://python-all.ru/2.7/library/email.generator.html#email.generator.Generator). Этого достаточно для реализации файлоподобного API, чтобы экземпляры [`Generator`](https://python-all.ru/2.7/library/email.generator.html#email.generator.Generator) можно было использовать в расширенных операторах print.

Для удобства можно обратиться к методам `Message.as_string()` и `str(aMessage)`, также известным как `Message.__str__()`, которые упрощают создание форматированного строкового представления объекта сообщения. Подробнее см. [`email.message`](https://python-all.ru/2.7/library/email.message.html#module-email.message).

Модуль [`email.generator`](https://python-all.ru/2.7/library/email.generator.html#module-email.generator) также предоставляет производный класс, называемый [`DecodedGenerator`](https://python-all.ru/2.7/library/email.generator.html#email.generator.DecodedGenerator), который похож на базовый класс [`Generator`](https://python-all.ru/2.7/library/email.generator.html#email.generator.Generator), за исключением того, что не-*text* части заменяются строкой формата, представляющей часть.

#### `class email.generator.DecodedGenerator(outfp[, mangle_from_[, maxheaderlen[, fmt]]])`

Этот класс, производный от [`Generator`](https://python-all.ru/2.7/library/email.generator.html#email.generator.Generator), проходит по всем вложенным частям сообщения. Если вложенная часть имеет основной тип *text*, то выводится декодированная полезная нагрузка этой части. Необязательные параметры *\_mangle\_from\_* и *maxheaderlen* работают так же, как в базовом классе [`Generator`](https://python-all.ru/2.7/library/email.generator.html#email.generator.Generator).

Если вложенная часть не имеет основного типа *text*, необязательный *fmt* – это строка формата, используемая вместо полезной нагрузки сообщения. *fmt* разворачивается со следующими ключевыми словами в формате `%(keyword)s`:

- `type` – полный MIME-тип части не-*text*
- `maintype` – основной MIME-тип части не-*text*
- `subtype` – подтип MIME части не-*text*
- `filename` – имя файла части не-*text*
- `description` – описание, связанное с частью не-*text*
- `encoding` – кодировка передачи содержимого части не-*text*

Значение по умолчанию для *fmt* – `None`, то есть

```python
[Non-text (%(type)s) part of message omitted, filename %(filename)s]
```

Добавлено в версии 2.2.2.

Изменено в версии 2.5: Ранее устаревший метод [`__call__()`](https://python-all.ru/2.7/reference/datamodel.html#object.__call__) был удалён.

Сноски

**[1](https://python-all.ru/2.7/library/email.generator.html#id1)**

Это утверждение предполагает использование подходящей настройки для аргумента `unixfrom` и установку maxheaderlen=0 (что сохранит исходную длину строк). Кроме того, это не совсем верно, поскольку во многих случаях серии пробелов в заголовках сворачиваются в одиночные пробелы. Последнее является ошибкой, которая будет исправлена.
