# `email.message.Message`: Представлення повідомлення електронної пошти за допомогою API `compat32`

Клас `Message` дуже схожий на клас `EmailMessage`, але без методів, доданих цим класом, і з поведінкою за замовчуванням деяких інших методів дещо іншою. Ми також документуємо тут деякі методи, які, хоча й підтримуються класом `EmailMessage`, не рекомендуються, якщо ви не маєте справу зі застарілим кодом.

Філософія та структура двох класів є однаковими.

Цей документ описує поведінку за умовчанням (для `Message`) політики `Compat32`. Якщо ви збираєтеся використовувати іншу політику, замість неї слід використовувати клас `EmailMessage`.

Повідомлення електронної пошти складається з заголовків і корисного навантаження. Заголовки мають бути в стилі RFC 5322 імен і значень, де назва поля та значення розділені двокрапкою. Двокрапка не є частиною ані імені поля, ані значення поля. Корисне навантаження може бути простим текстовим повідомленням, або двійковим об’єктом, або структурованою послідовністю підповідомлень, кожне з яких має власний набір заголовків і власне корисне навантаження. Останній тип корисного навантаження вказується повідомленням, що має тип MIME, наприклад multipart/* або message/rfc822.

Концептуальна модель, яку забезпечує об’єкт `Message`, — це впорядкований словник заголовків із додатковими методами для доступу до спеціалізованої інформації із заголовків, для доступу до корисного навантаження, для генерації серіалізованої версії повідомлення та для рекурсивного проходячи по дереву предметів. Зауважте, що дублікати заголовків підтримуються, але для доступу до них потрібно використовувати спеціальні методи.

Псевдословник `Message` індексується іменами заголовків, які мають бути значеннями ASCII. Значення словника - це рядки, які мають містити лише символи ASCII; існує певна особлива обробка для вводу не-ASCII, але вона не завжди дає правильні результати. Заголовки зберігаються та повертаються у формі зі збереженням регістру, але імена полів зіставляються без урахування регістру. Також може бути єдиний заголовок конверта, також відомий як заголовок Unix-From або заголовок `From_`. Корисне навантаження — це або рядок, або байти, у випадку простих об’єктів повідомлення, або список об’єктів `Message` для документів-контейнерів MIME (наприклад, multipart/* і повідомлення/rfc822).

Ось методи класу `Message`:

class email.message.Message(policy=compat32)

  Якщо вказано policy (вона має бути екземпляром класу `policy`), використовуйте вказані в ньому правила для оновлення та серіалізації представлення повідомлення. Якщо policy не встановлено, використовуйте політику `compat32`, яка підтримує зворотну сумісність із версією пакета електронної пошти Python 3.2. Для отримання додаткової інформації дивіться документацію `policy`.

  Змінено в версії 3.3: Додано аргумент ключового слова policy.

  as_string(unixfrom=False, maxheaderlen=0, policy=None)

    Повернути все повідомлення зведеним у вигляді рядка. Якщо необов’язковий параметр unixfrom має значення true, заголовок конверта включається до поверненого рядка. unixfrom за умовчанням має значення `False`. З міркувань зворотної сумісності maxheaderlen за замовчуванням має значення `0`, тому, якщо ви бажаєте інше значення, ви повинні його явно змінити (значення, указане для max_line_length у політиці, ігноруватиметься цим методом). Аргумент policy можна використовувати для заміни політики за замовчуванням, отриманої з екземпляра повідомлення. Це можна використовувати для керування частиною форматування, створеного методом, оскільки вказану політику буде передано `генератору`.

    Зведення повідомлення може викликати зміни в `Message`, якщо для завершення перетворення в рядок необхідно вказати значення за замовчуванням (наприклад, можуть бути створені або змінені межі MIME).

    Note that this method is provided as a convenience and may not always format the message the way you want. For example, by default it does not do the mangling of lines that begin with `From` that is required by the Unix mbox format. For more flexibility, instantiate a `Generator` instance and use its `flatten()` method directly. For example:

        from io import StringIO
        from email.generator import Generator
        fp = StringIO()
        g = Generator(fp, mangle_from_=True, maxheaderlen=60)
        g.flatten(msg)
        text = fp.getvalue()

    Якщо об’єкт повідомлення містить двійкові дані, які не закодовані відповідно до стандартів RFC, невідповідні дані буде замінено кодовими точками Unicode «невідомий символ». (Див. також `as_bytes()` і `BytesGenerator`.)

    Змінено в версії 3.4: було додано аргумент ключового слова policy.

  __str__()

    Equivalent to `as_string()`. Allows `str(msg)` to produce a string containing the formatted message.

  as_bytes(unixfrom=False, policy=None)

    Повертає все повідомлення зведене як об’єкт bytes. Якщо необов’язковий параметр unixfrom має значення true, заголовок конверта включається до поверненого рядка. unixfrom за умовчанням має значення `False`. Аргумент policy можна використовувати для заміни політики за замовчуванням, отриманої з екземпляра повідомлення. Це можна використовувати для керування частиною форматування, створеного методом, оскільки вказану політику буде передано до `BytesGenerator`.

    Зведення повідомлення може викликати зміни в `Message`, якщо для завершення перетворення в рядок необхідно вказати значення за замовчуванням (наприклад, можуть бути створені або змінені межі MIME).

    Note that this method is provided as a convenience and may not always format the message the way you want. For example, by default it does not do the mangling of lines that begin with `From` that is required by the Unix mbox format. For more flexibility, instantiate a `BytesGenerator` instance and use its `flatten()` method directly. For example:

        from io import BytesIO
        from email.generator import BytesGenerator
        fp = BytesIO()
        g = BytesGenerator(fp, mangle_from_=True, maxheaderlen=60)
        g.flatten(msg)
        text = fp.getvalue()

    Нове в версії 3.4.

  __bytes__()

    Equivalent to `as_bytes()`. Allows `bytes(msg)` to produce a bytes object containing the formatted message.

    Нове в версії 3.4.

  is_multipart()

    Повертає `True`, якщо корисним навантаженням повідомлення є список sub-`Message` об’єктів, інакше повертає `False`. Коли `is_multipart()` повертає `False`, корисним навантаженням має бути рядковий об’єкт (який може бути двійковим навантаженням у кодуванні CTE). (Зауважте, що `is_multipart()`, що повертає `True`, не обов’язково означає, що «msg.get_content_maintype() == „multipart“» поверне `True`. Наприклад, `is_multipart` буде повертає `True`, якщо `Message` має тип `message/rfc822`.)

  set_unixfrom(unixfrom)

    Встановіть заголовок конверта повідомлення на unixfrom, який має бути рядком.

  get_unixfrom()

    Повернути заголовок конверта повідомлення. За замовчуванням `None`, якщо заголовок конверта ніколи не встановлювався.

  attach(payload)

    Додайте вказане корисне навантаження до поточного корисного навантаження, яке має бути `None` або список об’єктів `Message` перед викликом. Після виклику корисним навантаженням завжди буде список об’єктів `Message`. Якщо ви хочете встановити корисне навантаження на скалярний об’єкт (наприклад, рядок), замість цього використовуйте `set_payload()`.

    Це застарілий метод. У класі `EmailMessage` його функціональні можливості замінені на `set_content()` і відповідні методи `make` і `add`.

  get_payload(i=None, decode=False)

    Повертає поточне корисне навантаження, яке буде списком об’єктів `Message`, якщо `is_multipart()` має значення `True`, або рядок, коли `is_multipart()` має значення `False`. Якщо корисним навантаженням є список, і ви змінюєте об’єкт списку, ви змінюєте корисне навантаження повідомлення на місці.

    З необов’язковим аргументом i `get_payload()` поверне i-й елемент корисного навантаження, починаючи з нуля, якщо `is_multipart()` має значення `True`. Помилка `IndexError` буде викликана, якщо i менше за 0 або більше або дорівнює кількості елементів у корисному навантаженні. Якщо корисне навантаження є рядком (тобто `is_multipart()` має значення `False`) і задано i, виникає `TypeError`.

    Необов’язковий decode — це прапорець, який вказує, чи слід декодувати корисне навантаження чи ні, відповідно до заголовка Content-Transfer-Encoding. Якщо значення `True` і повідомлення не складається з кількох частин, корисне навантаження буде декодовано, якщо значенням цього заголовка є `quoted-printable` або `base64`. Якщо використовується інше кодування або відсутній заголовок Content-Transfer-Encoding, корисне навантаження повертається як є (недекодоване). У всіх випадках повертається двійкове значення. Якщо повідомлення складається з кількох частин і прапорець decode має значення `True`, тоді повертається `None`. Якщо корисне навантаження є base64 і воно не було ідеально сформоване (відсутнє заповнення, символи поза алфавітом base64), тоді до властивості дефекту повідомлення буде додано відповідний дефект (`InvalidBase64PaddingDefect` або `InvalidBase64CharactersDefect` відповідно).

    Якщо decode має значення `False` (за замовчуванням), тіло повертається як рядок без декодування Content-Transfer-Encoding. Однак для Content-Transfer-Encoding 8 біт робиться спроба декодувати оригінальні байти за допомогою `charset`, визначеного заголовком Content-Type, використовуючи обробник помилок `replace`. Якщо `charset` не вказано, або якщо наданий `набір символів` не розпізнається пакетом електронної пошти, тіло декодується за допомогою набору символів ASCII за замовчуванням.

    Це застарілий метод. У класі `EmailMessage` його функції замінені на `get_content()` і `iter_parts()`.

  set_payload(payload, charset=None)

    Встановіть корисне навантаження всього об’єкта повідомлення на корисне навантаження. Клієнт відповідає за забезпечення інваріантів корисного навантаження. Додатковий charset встановлює стандартний набір символів повідомлення; подробиці див. `set_charset()`.

    Це застарілий метод. У класі `EmailMessage` його функціональність замінено на `set_content()`.

  set_charset(charset)

    Встановіть набір символів корисного навантаження на charset, який може бути екземпляром `Charset` (див. `email.charset`), рядком із назвою набору символів або `Жодного`. Якщо це рядок, його буде перетворено на екземпляр `Charset`. Якщо charset має значення `None`, параметр `charset` буде видалено із заголовка Content-Type (повідомлення не буде іншим чином змінено). Усе інше створить `TypeError`.

    Якщо немає існуючого заголовка MIME-Version, буде додано один. Якщо немає заголовка Content-Type, його буде додано зі значенням text/plain. Незалежно від того, чи існує заголовок Content-Type, його параметр `charset` буде встановлено на charset.output_charset. Якщо charset.input_charset і charset.output_charset відрізняються, корисне навантаження буде перекодовано в output_charset. Якщо немає існуючого заголовка Content-Transfer-Encoding, то корисне навантаження буде закодовано за потреби за допомогою вказаного `Charset` і заголовка з відповідним буде додано значення. Якщо заголовок Content-Transfer-Encoding вже існує, вважається, що корисне навантаження вже правильно закодовано за допомогою цього Content-Transfer-Encoding і не змінюється.

    Це застарілий метод. У класі `EmailMessage` його функціональність замінено параметром charset методу `email.emailmessage.EmailMessage.set_content()`.

  get_charset()

    Повертає екземпляр `Charset`, пов’язаний із корисним навантаженням повідомлення.

    Це застарілий метод. У класі `EmailMessage` завжди повертається `None`.

  Наступні методи реалізують схожий на відображення інтерфейс для доступу до заголовків повідомлення RFC 2822. Зверніть увагу, що існують деякі семантичні відмінності між цими методами та інтерфейсом звичайного відображення (тобто словника). Наприклад, у словнику немає дублікатів ключів, але тут можуть бути дублікати заголовків повідомлень. Крім того, у словниках немає гарантованого порядку ключів, які повертає `keys()`, але в об’єкті `Message` заголовки завжди повертаються в тому порядку, в якому вони з’являлися у вихідному повідомленні або були додані до повідомлення пізніше. Будь-який видалений і потім знову доданий заголовок завжди додається в кінець списку заголовків.

  Ці семантичні відмінності є навмисними та спрямовані на максимальну зручність.

  Зауважте, що в усіх випадках будь-який заголовок конверта, присутній у повідомленні, не включається в інтерфейс зіставлення.

  In a model generated from bytes, any header values that (in contravention of the RFCs) contain non-ASCII bytes will, when retrieved through this interface, be represented as `Header` objects with a charset of `unknown-8bit`.

  __len__()

    Повертає загальну кількість заголовків, включаючи дублікати.

  __contains__(name)

    Повертає `True`, якщо об’єкт повідомлення має поле з назвою name. Зіставлення виконується без урахування регістру, і ім’я не повинно містити двокрапку в кінці. Використовується для оператора `in`, наприклад:

        if 'message-id' in myMessage:
           print('Message-ID:', myMessage['message-id'])

  __getitem__(name)

    Повертає значення названого поля заголовка. ім’я не повинно включати двокрапку-роздільник полів. Якщо заголовок відсутній, повертається `None`; a `KeyError` ніколи не виникає.

    Зауважте, що якщо назване поле з’являється більше одного разу в заголовках повідомлення, яке саме значення полів буде повернуто, не визначено. Використовуйте метод `get_all()`, щоб отримати значення всіх наявних іменованих заголовків.

  __setitem__(name, val)

    Додайте до повідомлення заголовок із назвою поля name і значенням val. Поле додається в кінці існуючих полів повідомлення.

    Зауважте, що це не перезаписує та не видаляє будь-який існуючий заголовок із такою самою назвою. Якщо ви хочете переконатися, що новий заголовок є єдиним у повідомленні з назвою поля name, спочатку видаліть це поле, наприклад:

        del msg['subject']
        msg['subject'] = 'Python roolz!'

  __delitem__(name)

    Видалити всі входження поля з назвою name із заголовків повідомлення. Жодного винятку не створюється, якщо назване поле відсутнє в заголовках.

  keys()

    Повертає список імен усіх полів заголовка повідомлення.

  values()

    Повертає список усіх значень полів повідомлення.

  items()

    Повертає список із двох кортежів, що містить усі заголовки та значення полів повідомлення.

  get(name, failobj=None)

    Return the value of the named header field. This is identical to `__getitem__()` except that optional failobj is returned if the named header is missing (defaults to `None`).

  Ось кілька додаткових корисних методів:

  get_all(name, failobj=None)

    Повертає список усіх значень для поля з назвою name. Якщо в повідомленні немає таких іменованих заголовків, повертається failobj (за замовчуванням `None`).

  add_header(_name, _value, **_params)

    Розширене налаштування заголовка. Цей метод подібний до `__setitem__()` за винятком того, що додаткові параметри заголовка можуть бути надані як аргументи ключового слова. _name — це поле заголовка, яке потрібно додати, а _value — це основне значення для заголовка.

    Для кожного елемента в словнику аргументів ключових слів _params ключ береться як ім’я параметра, а символи підкреслення перетворюються на тире (оскільки тире заборонені в ідентифікаторах Python). Зазвичай параметр буде додано як `key="value"`, якщо значення не буде `None`, у цьому випадку буде додано лише ключ. Якщо значення містить символи, відмінні від ASCII, його можна вказати як трикортеж у форматі `(НАБІР СИМВОЛІВ, МОВА, ЗНАЧЕННЯ)`, де `НАБІР СИГНАЛОВ` – це рядок із назвою набору символів, який буде використано для кодування значення `LANGUAGE` зазвичай можна встановити на `None` або порожній рядок (перегляньте RFC 2231 для інших можливостей), а `VALUE` є значенням рядка, що містить кодові точки не-ASCII . Якщо три кортежу не передано і значення містить символи, відмінні від ASCII, воно автоматично кодується у форматі RFC 2231 з використанням `CHARSET` `utf-8` і `LANGUAGE` з `Жодного`.

    Ось приклад:

        msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')

    Це додасть заголовок, який виглядає так:

        Content-Disposition: attachment; filename="bud.gif"

    Приклад із символами, відмінними від ASCII:

        msg.add_header('Content-Disposition', 'attachment',
                       filename=('iso-8859-1', '', 'Fußballer.ppt'))

    Що виробляє

        Content-Disposition: attachment; filename*="iso-8859-1''Fu%DFballer.ppt"

  replace_header(_name, _value)

    Замінити заголовок. Замініть перший знайдений у повідомленні заголовок, який відповідає _name, зберігаючи порядок заголовків і регістр імені поля. Якщо відповідного заголовка не знайдено, виникає `KeyError`.

  get_content_type()

    Повернути тип вмісту повідомлення. Повернений рядок приводиться до нижнього регістру у формі maintype/subtype. Якщо в повідомленні не було заголовка Content-Type, буде повернено тип за замовчуванням, заданий `get_default_type()`. Оскільки відповідно до RFC 2045 повідомлення завжди мають тип за замовчуванням, `get_content_type()` завжди повертатиме значення.

    RFC 2045 визначає тип повідомлення за замовчуванням як text/plain, якщо воно не з’являється всередині контейнера multipart/digest, у такому випадку це буде message/rfc822 . Якщо заголовок Content-Type має недійсну специфікацію типу, RFC 2045 вимагає, щоб типовим типом був text/plain.

  get_content_maintype()

    Повернути основний тип вмісту повідомлення. Це maintype частина рядка, яку повертає `get_content_type()`.

  get_content_subtype()

    Повернути тип підвмісту повідомлення. Це subtype частина рядка, яку повертає `get_content_type()`.

  get_default_type()

    Повернути типовий тип вмісту. Більшість повідомлень мають стандартний тип вмісту text/plain, за винятком повідомлень, які є підчастинами контейнерів multipart/digest. Такі підчастини мають типовий тип вмісту message/rfc822.

  set_default_type(ctype)

    Встановіть тип вмісту за замовчуванням. ctype має бути text/plain або message/rfc822, хоча це не обов’язково. Стандартний тип вмісту не зберігається в заголовку Content-Type.

  get_params(failobj=None, header='content-type', unquote=True)

    Повернути параметри Content-Type повідомлення у вигляді списку. Елементи повернутого списку — це 2-кортежі пар ключ/значення, розділені знаком `'='`. Ліва сторона `'='` є ключем, а права частина - значенням. Якщо в параметрі немає знака `'='`, значенням є порожній рядок, інакше значення відповідає опису в `get_param()` і не береться в лапки, якщо необов’язковий unquote має значення `True` ( за замовчуванням).

    Необов’язковий failobj — це об’єкт, який повертається, якщо немає заголовка Content-Type. Додатковий header – це заголовок для пошуку замість Content-Type.

    Це застарілий метод. У класі `EmailMessage` його функціональність замінена властивістю params окремих об’єктів заголовка, які повертаються методами доступу до заголовка.

  get_param(param, failobj=None, header='content-type', unquote=True)

    Повертає значення параметра param заголовка Content-Type у вигляді рядка. Якщо повідомлення не має заголовка Content-Type або немає такого параметра, повертається failobj (за замовчуванням `None`).

    Необов’язковий заголовок, якщо задано, визначає заголовок повідомлення, який слід використовувати замість Content-Type.

    Ключі параметрів завжди порівнюються без урахування регістру. Значення, що повертається, може бути рядком або кортежем із трьох, якщо параметр було закодовано RFC 2231. Якщо це 3-кортеж, елементи значення мають форму `(НАБІР СИМВОЛІВ, МОВА, ЗНАЧЕННЯ)`. Зауважте, що як для `CHARSET`, так і для `LANGUAGE` може бути `None`, у цьому випадку вам слід вважати, що `VALUE` закодовано в `us-ascii`. Зазвичай ви можете ігнорувати `LANGUAGE`.

    Якщо вашій програмі байдуже, чи був параметр закодований як у RFC 2231, ви можете згорнути значення параметра, викликавши `email.utils.collapse_rfc2231_value()`, передавши значення, що повертається з `get_param()`. Це поверне відповідним чином декодований рядок Unicode, якщо значення є кортежем, або оригінальний рядок без лапок, якщо це не так. Наприклад:

        rawparam = msg.get_param('foo')
        param = email.utils.collapse_rfc2231_value(rawparam)

    У будь-якому випадку значення параметра (або повернений рядок, або елемент `VALUE` у 3-кортежі) завжди не береться в лапки, якщо для unquote не встановлено значення `False`.

    Це застарілий метод. У класі `EmailMessage` його функціональність замінена властивістю params окремих об’єктів заголовка, які повертаються методами доступу до заголовка.

  set_param(param, value, header='Content-Type', requote=True, charset=None, language='', replace=False)

    Установіть параметр у заголовку Content-Type. Якщо параметр уже існує в заголовку, його значення буде замінено на value. Якщо заголовок Content-Type ще не визначено для цього повідомлення, для нього буде встановлено значення text/plain, а нове значення параметра буде додано відповідно до RFC 2045.

    Необов’язковий header визначає альтернативний заголовок Content-Type, і всі параметри будуть взяті в лапки, якщо необов’язковий requote не має значення `False` (за замовчуванням це `True`).

    Якщо вказано необов’язковий charset, параметр буде закодовано відповідно до RFC 2231. Необов’язкова мова вказує мову RFC 2231, за умовчанням порожній рядок. І charset, і language мають бути рядками.

    Якщо replace має значення `False` (за замовчуванням), заголовок переміщується в кінець списку заголовків. Якщо replace має значення `True`, заголовок буде оновлено на місці.

    Змінено в версії 3.4: Додано ключове слово `replace`.

  del_param(param, header='content-type', requote=True)

    Повністю вилучіть вказаний параметр із заголовка Content-Type. Заголовок буде перезаписано на місці без параметра чи його значення. Усі значення будуть взяті в лапки за необхідності, якщо requote не має значення `False` (за замовчуванням `True`). Необов’язковий заголовок визначає альтернативу Content-Type.

  set_type(type, header='Content-Type', requote=True)

    Встановіть основний тип і підтип для заголовка Content-Type. type має бути рядком у формі maintype/subtype, інакше виникає `ValueError`.

    Цей метод замінює заголовок Content-Type, зберігаючи всі параметри на місці. Якщо requote має значення `False`, це залишає існуючі лапки заголовка як є, інакше параметри будуть взяті в лапки (за замовчуванням).

    Альтернативний заголовок можна вказати в аргументі header. Коли встановлено заголовок Content-Type, також додається заголовок MIME-Version.

    Це застарілий метод. У класі `EmailMessage` його функціональність замінена методами `make_` і `add_`.

  get_filename(failobj=None)

    Повертає значення параметра `filename` заголовка Content-Disposition повідомлення. Якщо заголовок не має параметра `filename`, цей метод повертається до пошуку параметра `name` у заголовку Content-Type. Якщо нічого не знайдено або відсутній заголовок, повертається failobj. Повернений рядок завжди буде без лапок відповідно до `email.utils.unquote()`.

  get_boundary(failobj=None)

    Повертає значення параметра `boundary` заголовка Content-Type повідомлення або failobj, якщо заголовок відсутній або не має параметра `boundary`. Повернений рядок завжди буде без лапок відповідно до `email.utils.unquote()`.

  set_boundary(boundary)

    Установіть для параметра `boundary` заголовка Content-Type значення boundary. `set_boundary()` завжди братиме boundary у лапки, якщо необхідно. Помилка `HeaderParseError` виникає, якщо об’єкт повідомлення не має заголовка Content-Type.

    Зауважте, що використання цього методу дещо відрізняється від видалення старого заголовка Content-Type і додавання нового з новою межею за допомогою `add_header()`, оскільки `set_boundary()` зберігає порядок заголовок Content-Type у списку заголовків. Однак він не зберігає будь-які рядки продовження, які могли бути присутніми в оригінальному заголовку Content-Type.

  get_content_charset(failobj=None)

    Повертає параметр `charset` заголовка Content-Type у нижньому регістрі. Якщо немає заголовка Content-Type або цей заголовок не має параметра `charset`, повертається failobj.

    Зауважте, що цей метод відрізняється від `get_charset()`, який повертає екземпляр `Charset` для стандартного кодування тіла повідомлення.

  get_charsets(failobj=None)

    Повернути список із назвами наборів символів у повідомленні. Якщо повідомлення є multipart, тоді список міститиме один елемент для кожної підчастини в корисному навантаженні, інакше це буде список довжиною 1.

    Кожен елемент у списку буде рядком, який є значенням параметра `charset` у заголовку Content-Type для представленої підчастини. Однак, якщо підчастина не має заголовка Content-Type, параметра `charset` або не належить до основного типу MIME text, тоді цей елемент у списку, що повертається, буде failobj.

  get_content_disposition()

    Повертає значення в нижньому регістрі (без параметрів) заголовка повідомлення Content-Disposition, якщо воно є, або `None`. Можливі значення для цього методу: inline, attachment або `None`, якщо повідомлення слідує за RFC 2183.

    Нове в версії 3.5.

  walk()

    Метод `walk()` — це універсальний генератор, який можна використовувати для перебору всіх частин і підчастин дерева об’єктів повідомлення в порядку проходження спочатку в глибину. Ви зазвичай використовуєте `walk()` як ітератор у циклі `for`; кожна ітерація повертає наступну підчастину.

    Ось приклад, який друкує тип MIME кожної частини структури повідомлення, що складається з кількох частин:

        >>> for part in msg.walk():
        ...     print(part.get_content_type())
        multipart/report
        text/plain
        message/delivery-status
        text/plain
        text/plain
        message/rfc822
        text/plain

    `walk` повторює підчастини будь-якої частини, де `is_multipart()` повертає `True`, навіть якщо `msg.get_content_maintype() == 'multipart'` може повернути `False`. Ми можемо побачити це в нашому прикладі, використовуючи допоміжну функцію налагодження `_structure`:

        >>> for part in msg.walk():
        ...     print(part.get_content_maintype() == 'multipart',
        ...           part.is_multipart())
        True True
        False False
        False True
        False False
        False False
        False True
        False False
        >>> _structure(msg)
        multipart/report
            text/plain
            message/delivery-status
                text/plain
                text/plain
            message/rfc822
                text/plain

    Тут частини `message` не є `multiparts`, але вони містять підчастини. `is_multipart()` повертає `True` і `walk` спускається до підчастин.

  Об’єкти `Message` також можуть додатково містити два атрибути екземпляра, які можна використовувати під час генерації простого тексту повідомлення MIME.

  preamble

    Формат документа MIME допускає деякий текст між порожнім рядком після заголовків і першим обмежувальним рядком із складених частин. Зазвичай цей текст ніколи не відображається в програмі читання пошти з підтримкою MIME, оскільки він виходить за рамки стандартної броні MIME. Однак під час перегляду необробленого тексту повідомлення або під час перегляду повідомлення в програмі читання, яка не підтримує MIME, цей текст може стати видимим.

    Атрибут преамбула містить цей провідний додатковий текст для документів MIME. Коли `Parser` виявляє текст після заголовків, але перед першим обмежувальним рядком, він призначає цей текст атрибуту преамбула повідомлення. Коли `Generator` записує звичайне текстове представлення повідомлення MIME і виявляє, що повідомлення має атрибут преамбула, він записує цей текст у область між заголовками та перша межа. Перегляньте `email.parser` і `email.generator` для деталей.

    Зауважте, що якщо об’єкт повідомлення не має преамбули, атрибут preamble матиме значення `None`.

  epilogue

    Атрибут epilogue діє так само, як і атрибут preamble, за винятком того, що він містить текст, який з’являється між останньою межею та кінцем повідомлення.

    Вам не потрібно встановлювати епілог порожнім рядком, щоб `Generator` друкував новий рядок у кінці файлу.

  defects

    Атрибут defects містить список усіх проблем, виявлених під час аналізу цього повідомлення. Перегляньте `email.errors` для детального опису можливих дефектів аналізу.