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

---

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

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

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

Вывод в [`bytes`](https://python-all.ru/3.2/library/functions.html#bytes) можно получить с помощью класса [`BytesGenerator`](https://python-all.ru/3.2/library/email.generator.html#email.generator.BytesGenerator). Если структура объекта сообщения содержит не-ASCII байты, метод [`flatten()`](https://python-all.ru/3.2/library/email.generator.html#email.generator.BytesGenerator.flatten) этого генератора выдаст исходные байты. Разбор двоичного сообщения и последующее уплощение с помощью [`BytesGenerator`](https://python-all.ru/3.2/library/email.generator.html#email.generator.BytesGenerator) должно быть идемпотентным для сообщений, соответствующих стандартам.

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

#### `class email.generator.Generator(outfp, mangle_from_=True, maxheaderlen=78)`

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

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

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

Другие публичные методы [`Generator`](https://python-all.ru/3.2/library/email.generator.html#email.generator.Generator):

#### `flatten(msg, unixfrom=False, linesep='\n')`

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

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

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

Необязательный параметр *linesep* задаёт символ разделителя строк, используемый для завершения строк в выводе. По умолчанию используются `\n`, поскольку это наиболее подходящее значение для кода приложений на Python (другие пакеты библиотек ожидают строки, разделённые `\n`). `linesep=\r\n` можно использовать для создания вывода с разделителями строк, соответствующими RFC.

Сообщения, разобранные с помощью анализатора Bytes, имеющие *Content-Transfer-Encoding* со значением 8bit, будут преобразованы для использования 7bit Content-Transfer-Encoding. Не-ASCII байты в заголовках будут закодированы в соответствии с [**RFC 2047**](https://python-all.ru/3.2/library/email.generator.html) с кодировкой *unknown-8bit*.

Изменено в версии 3.2: Добавлена поддержка перекодировки тел сообщений 8bit и аргумента *linesep*.

#### `clone(fp)`

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

#### `write(s)`

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

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

#### `class email.generator.BytesGenerator(outfp, mangle_from_=True, maxheaderlen=78)`

Конструктор класса [`BytesGenerator`](https://python-all.ru/3.2/library/email.generator.html#email.generator.BytesGenerator) принимает аргумент – двоичный [*файлоподобный объект*](https://python-all.ru/3.2/glossary.html#term-file-like-object) с именем *outfp*. *outfp* должен поддерживать метод [`write()`](https://python-all.ru/3.2/library/email.generator.html#email.generator.BytesGenerator.write), который принимает двоичные данные.

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

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

Другие публичные методы [`BytesGenerator`](https://python-all.ru/3.2/library/email.generator.html#email.generator.BytesGenerator):

#### `flatten(msg, unixfrom=False, linesep='n')`

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

Сообщения, разобранные с помощью Bytes parser, которые имеют *Content-Transfer-Encoding* равный 8bit, будут восстановлены как 8bit, если они не были изменены.

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

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

Необязательный параметр *linesep* задаёт символ разделителя строк, используемый для завершения строк в выводе. По умолчанию используются `\n`, поскольку это наиболее подходящее значение для кода приложений на Python (другие пакеты библиотек ожидают строки, разделённые `\n`). `linesep=\r\n` можно использовать для создания вывода с разделителями строк, соответствующими RFC.

#### `clone(fp)`

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

#### `write(s)`

Write the string *s* to the underlying file object. *s* is encoded using the `ASCII` codec and written to the *write* method of the *outfp* *outfp* passed to the [`BytesGenerator`](https://python-all.ru/3.2/library/email.generator.html#email.generator.BytesGenerator)‘s constructor. This provides just enough file-like API for [`BytesGenerator`](https://python-all.ru/3.2/library/email.generator.html#email.generator.BytesGenerator) instances to be used in the [`print()`](https://python-all.ru/3.2/library/functions.html#print) function.

Новое в версии 3.2.

The [`email.generator`](https://python-all.ru/3.2/library/email.generator.html#module-email.generator) module also provides a derived class, called [`DecodedGenerator`](https://python-all.ru/3.2/library/email.generator.html#email.generator.DecodedGenerator) which is like the [`Generator`](https://python-all.ru/3.2/library/email.generator.html#email.generator.Generator) base class, except that non-*text* parts are substituted with a format string representing the part.

#### `class email.generator.DecodedGenerator(outfp, mangle_from_=True, maxheaderlen=78, fmt=None)`

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

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

- `type` – Full MIME type of the non-*text* part
- `maintype` – Main MIME type of the non-*text* part
- `subtype` – Sub-MIME type of the non-*text* part
- `filename` – Filename of the non-*text* part
- `description` – Description associated with the non-*text* part
- `encoding` – Content transfer encoding of the non-*text* part

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

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

Сноски

| [\[1\]](https://python-all.ru/3.2/library/email.generator.html#id1) | Это утверждение предполагает, что используется подходящая настройка для аргумента `unixfrom` и что установлено maxheaderlen=0 (что сохранит исходные длины строк). Кроме того, это не совсем верно, поскольку во многих случаях последовательности пробелов в заголовках схлопываются в одиночные пробелы. Последнее является ошибкой, которая в конечном итоге будет исправлена. |
| --- | --- |
