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

mailbox.md

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

1> **Источник:** https://python-all.ru/3.3/library/mailbox.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 19.4. [`mailbox`](https://python-all.ru/3.3/library/mailbox.html#module-mailbox) – Работа с почтовыми ящиками в различных форматах89Этот модуль определяет два класса: [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) и [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message), для доступа к почтовым ящикам на диске и управления ими, а также для работы с содержащимися в них сообщениями. [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) предоставляет словареподобное отображение ключей на сообщения. [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message) расширяет класс [`email.message`](https://python-all.ru/3.3/library/email.message.html#module-email.message) модуля [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message), добавляя формат-специфичное состояние и поведение. Поддерживаемые форматы почтовых ящиков: Maildir, mbox, MH, Babyl и MMDF.1011> **См. также**12>13> **Модуль [`email`](https://python-all.ru/3.3/library/email.html#module-email)**14>15> Представление сообщений и управление ими.1617## 19.4.1. [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) объекты1819#### `class mailbox.Mailbox`2021Почтовый ящик, который можно просматривать и изменять.2223Класс [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) определяет интерфейс и не предназначен для создания экземпляров. Вместо этого от [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) должны наследоваться подклассы, специфичные для формата, а код должен создавать экземпляры конкретного подкласса.2425Интерфейс [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) напоминает словарь: небольшие ключи соответствуют сообщениям. Ключи выдаются экземпляром [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox), с которым они будут использоваться, и имеют смысл только для этого экземпляра [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox). Ключ продолжает идентифицировать сообщение, даже если соответствующее сообщение изменяется, например, заменяется другим сообщением.2627Сообщения можно добавлять в экземпляр [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) с помощью метода, подобного set, [`add()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.add), и удалять с помощью инструкции `del` или методов, подобных set, [`remove()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.remove) и [`discard()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.discard).2829Семантика интерфейса [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) отличается от семантики словаря в некоторых важных аспектах. При каждом запросе сообщения создаётся новое представление (обычно экземпляр [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message)) на основе текущего состояния почтового ящика. Аналогично, при добавлении сообщения в экземпляр [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) содержимое переданного представления сообщения копируется. Ни в одном из случаев экземпляр [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) не хранит ссылку на представление сообщения.3031Итератор по умолчанию [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) перебирает представления сообщений, а не ключи, как это делает итератор словаря по умолчанию. Более того, изменение почтового ящика во время итерации безопасно и имеет чётко определённое поведение. Сообщения, добавленные в почтовый ящик после создания итератора, не будут видны итератору. Сообщения, удалённые из почтового ящика до того, как итератор вернёт их, будут молча пропущены, хотя использование ключа от итератора может привести к исключению [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError), если соответствующее сообщение будет впоследствии удалено.3233> **Предупреждение**34>35> Следует соблюдать осторожность при изменении почтовых ящиков, которые могут одновременно изменяться другим процессом. Самый безопасный формат почтового ящика для таких задач – Maildir; следует избегать использования однофайловых форматов, таких как mbox, для одновременной записи. При изменении почтового ящика *необходимо* заблокировать его, вызвав методы [`lock()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.lock) и [`unlock()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.unlock) *перед* чтением любых сообщений в файле или внесением любых изменений путём добавления или удаления сообщения. Неблокировка почтового ящика может привести к потере сообщений или повреждению всего почтового ящика.3637Экземпляры [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) имеют следующие методы:3839#### `add(message)`4041Добавляет *сообщение* в почтовый ящик и возвращает ключ, который был ему присвоен.4243Параметр *message* может быть экземпляром [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message), экземпляром [`email.message.Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message), строкой, байтовой строкой или файлоподобным объектом (который должен быть открыт в бинарном режиме). Если *message* является экземпляром соответствующего формат-специфичного подкласса [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message) (например, если это экземпляр [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) и данный экземпляр является [`mbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mbox)), используется его формат-специфичная информация. В противном случае используются разумные значения по умолчанию для формат-специфичной информации.4445Изменено в версии 3.2: Добавлена поддержка двоичного ввода.4647#### `remove(key)`4849#### `__delitem__(key)`5051#### `discard(key)`5253Удаляет сообщение, соответствующее *ключу*, из почтового ящика.5455Если такого сообщения не существует, исключение [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError) возбуждается, если метод был вызван как [`remove()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.remove) или [`__delitem__()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.__delitem__), но исключение не возбуждается, если метод был вызван как [`discard()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.discard). Поведение [`discard()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.discard) может быть предпочтительнее, если базовый формат почтового ящика поддерживает одновременное изменение другими процессами.5657#### `__setitem__(key, message)`5859Заменяет сообщение, соответствующее *key*, на *message*. Возбуждает исключение [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError), если сообщение, соответствующее *key*, ещё не существует.6061Как и для [`add()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.add), параметр *message* может быть экземпляром [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message), экземпляром [`email.message.Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message), строкой, байтовой строкой или файлоподобным объектом (который должен быть открыт в бинарном режиме). Если *message* является экземпляром соответствующего формат-специфичного подкласса [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message) (например, если это экземпляр [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) и данный экземпляр является [`mbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mbox)), используется его формат-специфичная информация. В противном случае формат-специфичная информация сообщения, которое в данный момент соответствует *key*, остаётся без изменений.6263#### `iterkeys()`6465#### `keys()`6667Возвращает итератор по всем ключам, если вызван как [`iterkeys()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.iterkeys), или возвращает список ключей, если вызван как [`keys()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.keys).6869#### `itervalues()`7071#### `__iter__()`7273#### `values()`7475Возвращает итератор по представлениям всех сообщений, если вызван как [`itervalues()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.itervalues) или [`__iter__()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.__iter__), или возвращает список таких представлений, если вызван как [`values()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.values). Сообщения представляются как экземпляры соответствующего формат-специфичного подкласса [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message), если только при инициализации экземпляра [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) не была указана пользовательская фабрика сообщений.7677> **Примечание**78>79> Поведение [`__iter__()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.__iter__) отличается от поведения словарей, которые перебирают ключи.8081#### `iteritems()`8283#### `items()`8485Возвращает итератор по парам (*ключ*, *сообщение*), где *ключ* – это ключ, а *сообщение* – представление сообщения, если метод вызван как [`iteritems()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.iteritems), или возвращает список таких пар, если вызван как [`items()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.items). Сообщения представляются как экземпляры соответствующего подкласса [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message), зависящего от формата, если только при инициализации экземпляра [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) не была указана пользовательская фабрика сообщений.8687#### `get(key, default=None)`8889#### `__getitem__(key)`9091Возвращает представление сообщения, соответствующего *ключу*. Если такое сообщение отсутствует, возвращается *значение по умолчанию*, если метод был вызван как [`get()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.get), и возбуждается исключение [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError), если метод был вызван как [`__getitem__()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.__getitem__). Сообщение представляется как экземпляр соответствующего подкласса [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message), зависящего от формата, если только при инициализации экземпляра [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) не была указана пользовательская фабрика сообщений.9293#### `get_message(key)`9495Возвращает представление сообщения, соответствующего *ключу*, в виде экземпляра соответствующего подкласса [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message), зависящего от формата, или возбуждает исключение [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError), если такое сообщение отсутствует.9697#### `get_bytes(key)`9899Возвращает байтовое представление сообщения, соответствующего *ключу*, или возбуждает исключение [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError), если такое сообщение отсутствует.100101Новое в версии 3.2.102103#### `get_string(key)`104105Возвращает строковое представление сообщения, соответствующего *ключу*, или возбуждает исключение [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError), если такое сообщение отсутствует. Сообщение обрабатывается через [`email.message.Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message) для преобразования в 7-битное чистое представление.106107#### `get_file(key)`108109Возвращает файлоподобное представление сообщения, соответствующего *ключу*, или возбуждает исключение [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError), если такое сообщение отсутствует. Файлоподобный объект ведет себя как открытый в бинарном режиме. Этот файл следует закрыть, когда он больше не нужен.110111Изменено в версии 3.2: файловый объект на самом деле является двоичным файлом; ранее он некорректно возвращался в текстовом режиме. Кроме того, теперь объект, подобный файлу, поддерживает протокол менеджера контекста: можно использовать оператор [`with`](https://python-all.ru/3.3/reference/compound_stmts.html#with) для автоматического закрытия.112113> **Примечание**114>115> В отличие от других представлений сообщений, файлоподобные представления не обязательно независимы от экземпляра [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox), который их создал, или от нижележащего почтового ящика. Более подробная документация предоставляется каждым подклассом.116117#### `__contains__(key)`118119Возвращает `True`, если *ключ* соответствует сообщению, и `False` в противном случае.120121#### `__len__()`122123Возвращает количество сообщений в почтовом ящике.124125#### `clear()`126127Удаляет все сообщения из почтового ящика.128129#### `pop(key, default=None)`130131Возвращает представление сообщения, соответствующего *ключу*, и удаляет сообщение. Если такое сообщение отсутствует, возвращает *значение по умолчанию*. Сообщение представляется как экземпляр соответствующего подкласса [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message), зависящего от формата, если только при инициализации экземпляра [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) не была указана пользовательская фабрика сообщений.132133#### `popitem()`134135Возвращает произвольную пару (*ключ*, *сообщение*), где *ключ* – это ключ, а *сообщение* – представление сообщения, и удаляет соответствующее сообщение. Если почтовый ящик пуст, возбуждает исключение [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError). Сообщение представляется как экземпляр соответствующего подкласса [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message), зависящего от формата, если только при инициализации экземпляра [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) не была указана пользовательская фабрика сообщений.136137#### `update(arg)`138139Параметр *arg* должен быть отображением *ключ**сообщение* или итерируемым объектом из пар (*ключ*, *сообщение*). Обновляет почтовый ящик так, что для каждого заданного *ключа* и *сообщения* сообщение, соответствующее *ключу*, устанавливается в *сообщение*, как если бы это было сделано с помощью [`__setitem__()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.__setitem__). Как и в случае с [`__setitem__()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.__setitem__), каждый *ключ* уже должен соответствовать сообщению в почтовом ящике, иначе будет возбуждено исключение [`KeyError`](https://python-all.ru/3.3/library/exceptions.html#KeyError), поэтому в общем случае неверно, чтобы *arg* был экземпляром [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox).140141> **Примечание**142>143> В отличие от словарей, именованные аргументы не поддерживаются.144145#### `flush()`146147Записывает все ожидающие изменения в файловую систему. Для некоторых подклассов [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) изменения всегда записываются немедленно, и [`flush()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox.flush) ничего не делает, но всё равно стоит выработать привычку вызывать этот метод.148149#### `lock()`150151Захватывает монопольную рекомендательную блокировку почтового ящика, чтобы другие процессы не изменяли его. Если блокировка недоступна, возбуждается исключение [`ExternalClashError`](https://python-all.ru/3.3/library/mailbox.html#mailbox.ExternalClashError). Конкретные механизмы блокировки зависят от формата почтового ящика. Следует *всегда* блокировать почтовый ящик перед внесением любых изменений в его содержимое.152153#### `unlock()`154155Освобождает блокировку почтового ящика, если она установлена.156157#### `close()`158159Сбрасывает почтовый ящик, разблокирует его при необходимости и закрывает все открытые файлы. Для некоторых подклассов [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) этот метод ничего не делает.160161### 19.4.1.1. [`Maildir`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Maildir)162163#### `class mailbox.Maildir(dirname, factory=None, create=True)`164165Подкласс [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) для почтовых ящиков в формате Maildir. Параметр *factory* – это вызываемый объект, который принимает файлоподобное представление сообщения (ведущее себя как открытое в двоичном режиме) и возвращает пользовательское представление. Если *factory* равно `None`, то [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage) используется как представление сообщения по умолчанию. Если *create* равно `True`, почтовый ящик создаётся, если он не существует.166167По историческим причинам *dirname* назван так, а не *path*.168169Maildir – это почтовый формат на основе каталогов, разработанный для агента передачи почты qmail и ныне широко поддерживаемый другими программами. Сообщения в почтовом ящике Maildir хранятся в отдельных файлах в общей структуре каталогов. Такая архитектура позволяет нескольким независимым программам получать доступ и изменять почтовые ящики Maildir без повреждения данных, поэтому файловая блокировка не требуется.170171Почтовые ящики Maildir содержат три подкаталога: `tmp`, `new` и `cur`. Сообщения сперва создаются в подкаталоге `tmp`, а затем перемещаются в подкаталог `new` для завершения доставки. Почтовый клиент может затем переместить сообщение в подкаталог `cur` и сохранить информацию о состоянии сообщения в специальном разделе «info», добавляемом к его имени файла.172173Также поддерживаются папки в стиле, введённом почтовым транспортным агентом Courier. Любой подкаталог основного почтового ящика считается папкой, если `'.'` является первым символом в его имени. Имена папок представляются объектами [`Maildir`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Maildir) без ведущего `'.'`. Каждая папка сама является почтовым ящиком Maildir, но не должна содержать другие папки. Вместо этого логическая вложенность указывается с помощью `'.'` для разделения уровней, например «Archived.2005.07».174175> **Примечание**176>177> Спецификация Maildir требует использования двоеточия (`':'`) в некоторых именах файлов сообщений. Однако некоторые операционные системы не допускают этот символ в именах файлов. Если вы хотите использовать формат, подобный Maildir, в такой операционной системе, следует указать другой символ для замены. Восклицательный знак (`'!'`) – популярный выбор. Например:178>179> ```python180> import mailbox181> mailbox.Maildir.colon = '!'182> ```183>184> Атрибут `colon` также может быть установлен для каждого экземпляра отдельно.185186Экземпляры [`Maildir`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Maildir) обладают всеми методами [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox), а также следующими:187188#### `list_folders()`189190Возвращает список имён всех папок.191192#### `get_folder(folder)`193194Возвращает экземпляр [`Maildir`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Maildir), представляющий папку с именем *folder*. Если папка не существует, возбуждается исключение [`NoSuchMailboxError`](https://python-all.ru/3.3/library/mailbox.html#mailbox.NoSuchMailboxError).195196#### `add_folder(folder)`197198Создаёт папку с именем *folder* и возвращает экземпляр [`Maildir`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Maildir), представляющий её.199200#### `remove_folder(folder)`201202Удаляет папку с именем *folder*. Если папка содержит какие-либо сообщения, будет выброшено исключение [`NotEmptyError`](https://python-all.ru/3.3/library/mailbox.html#mailbox.NotEmptyError), и папка не будет удалена.203204#### `clean()`205206Удаляет временные файлы из почтового ящика, к которым не было обращений за последние 36 часов. Спецификация Maildir утверждает, что программы чтения почты должны делать это время от времени.207208Некоторые методы [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox), реализованные в [`Maildir`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Maildir), заслуживают особых замечаний:209210#### `add(message)`211212#### `__setitem__(key, message)`213214#### `update(arg)`215216> **Предупреждение**217>218> Эти методы генерируют уникальные имена файлов на основе идентификатора текущего процесса. При использовании нескольких потоков возможны незамеченные конфликты имен, которые могут привести к повреждению почтового ящика, если потоки не скоординированы, чтобы избежать одновременного использования этих методов для управления одним и тем же почтовым ящиком.219220#### `flush()`221222Все изменения в почтовых ящиках Maildir применяются немедленно, поэтому этот метод ничего не делает.223224#### `lock()`225226#### `unlock()`227228Почтовые ящики Maildir не поддерживают (и не требуют) блокировку, поэтому эти методы ничего не делают.229230#### `close()`231232Экземпляры [`Maildir`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Maildir) не держат открытых файлов, а базовые почтовые ящики не поддерживают блокировку, поэтому этот метод ничего не делает.233234#### `get_file(key)`235236В зависимости от платформы может быть невозможно изменить или удалить нижележащее сообщение, пока возвращенный файл остается открытым.237238> **См. также**239>240> **[Страница руководства maildir из qmail](https://python-all.ru/3.3/library/mailbox.html)**241>242> Оригинальная спецификация формата.243>244> **[Использование формата maildir](https://python-all.ru/3.3/library/mailbox.html)**245>246> Заметки о Maildir от его создателя. Включают обновлённую схему создания имён и детали семантики «info».247>248> **[man-страница maildir из Courier](https://python-all.ru/3.3/library/mailbox.html)**249>250> Другая спецификация формата. Описывает распространённое расширение для поддержки папок.251252### 19.4.1.2. [`mbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mbox)253254#### `class mailbox.mbox(path, factory=None, create=True)`255256Подкласс [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) для почтовых ящиков в формате mbox. Параметр *factory* – это вызываемый объект, который принимает файлоподобное представление сообщения (которое ведёт себя как открытое в двоичном режиме) и возвращает пользовательское представление. Если *factory* равно `None`, то [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) используется как представление сообщения по умолчанию. Если *create* равно `True`, почтовый ящик создаётся, если он не существует.257258Формат mbox – это классический формат хранения почты в Unix-системах. Все сообщения в почтовом ящике mbox хранятся в одном файле, при этом начало каждого сообщения обозначается строкой, первые пять символов которой – «From ».259260Существует несколько вариантов формата mbox, призванных устранить предполагаемые недостатки оригинала. Ради совместимости [`mbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mbox) реализует оригинальный формат, который иногда называют *mboxo*. Это означает, что заголовок *Content-Length*, если он присутствует, игнорируется, а любые вхождения «From » в начале строки тела сообщения преобразуются в «\>From » при сохранении сообщения, хотя вхождения «\>From » не преобразуются обратно в «From » при чтении сообщения.261262Некоторые методы [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox), реализованные в [`mbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mbox), заслуживают особых замечаний:263264#### `get_file(key)`265266Использование файла после вызова `flush()` или `close()` на экземпляре [`mbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mbox) может привести к непредсказуемым результатам или возбудить исключение.267268#### `lock()`269270#### `unlock()`271272Используются три механизма блокировки: точечная блокировка и, если доступны, системные вызовы `flock()` и `lockf()`.273274> **См. также**275>276> **[Страница руководства mbox из qmail](https://python-all.ru/3.3/library/mailbox.html)**277>278> Спецификация формата и его разновидностей.279>280> **[Страница man mbox из tin](https://python-all.ru/3.3/library/mailbox.html)**281>282> Другая спецификация формата, с подробностями о блокировке.283>284> **[Настройка Netscape Mail в Unix: почему формат Content-Length плох](https://python-all.ru/3.3/library/mailbox.html)**285>286> Аргумент в пользу использования оригинального формата mbox, а не его вариации.287>288> **[«mbox» – это семейство нескольких взаимно несовместимых форматов почтовых ящиков](https://python-all.ru/3.3/library/mailbox.html)**289>290> История вариаций mbox.291292### 19.4.1.3. [`MH`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MH)293294#### `class mailbox.MH(path, factory=None, create=True)`295296Подкласс [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) для почтовых ящиков в формате MH. Параметр *factory* – это вызываемый объект, который принимает файлоподобное представление сообщения (которое ведёт себя так, как если бы было открыто в двоичном режиме) и возвращает пользовательское представление. Если *factory* равно `None`, в качестве представления сообщения по умолчанию используется [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage). Если *create* равно `True`, почтовый ящик создаётся, если он не существует.297298MH – это формат почтового ящика, основанный на каталогах, разработанный для системы обработки сообщений MH (почтового клиента). Каждое сообщение в почтовом ящике MH находится в собственном файле. Почтовый ящик MH может содержать другие почтовые ящики MH (называемые *папками*) в дополнение к сообщениям. Папки могут быть вложены неограниченно. Почтовые ящики MH также поддерживают *последовательности*, которые представляют собой именованные списки, используемые для логической группировки сообщений без перемещения их в подпапки. Последовательности определяются в файле `.mh_sequences` в каждой папке.299300Класс [`MH`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MH) управляет почтовыми ящиками MH, но не пытается эмулировать все поведения **mh**. В частности, он не изменяет и не зависит от файлов `context` или `.mh_profile`, которые используются **mh** для хранения своего состояния и конфигурации.301302Экземпляры [`MH`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MH) имеют все методы [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) в дополнение к следующим:303304#### `list_folders()`305306Возвращает список имён всех папок.307308#### `get_folder(folder)`309310Возвращает экземпляр [`MH`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MH), представляющий папку с именем *folder*. Исключение [`NoSuchMailboxError`](https://python-all.ru/3.3/library/mailbox.html#mailbox.NoSuchMailboxError) выбрасывается, если папка не существует.311312#### `add_folder(folder)`313314Создаёт папку с именем *folder* и возвращает экземпляр [`MH`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MH), представляющий её.315316#### `remove_folder(folder)`317318Удаляет папку с именем *folder*. Если папка содержит какие-либо сообщения, будет выброшено исключение [`NotEmptyError`](https://python-all.ru/3.3/library/mailbox.html#mailbox.NotEmptyError), и папка не будет удалена.319320#### `get_sequences()`321322Возвращает словарь, где имена последовательностей сопоставлены со списками ключей. Если последовательностей нет, возвращается пустой словарь.323324#### `set_sequences(sequences)`325326Переопределяет последовательности, существующие в почтовом ящике, на основе *sequences*, словаря имён, сопоставленных со списками ключей, как возвращаемый [`get_sequences()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MH.get_sequences).327328#### `pack()`329330Переименовывает сообщения в почтовом ящике по мере необходимости для устранения пропусков в нумерации. Записи в списке последовательностей обновляются соответствующим образом.331332> **Примечание**333>334> Ранее выданные ключи становятся недействительными в результате этой операции и не должны использоваться в дальнейшем.335336Некоторые методы [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox), реализованные в [`MH`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MH), заслуживают особых замечаний:337338#### `remove(key)`339340#### `__delitem__(key)`341342#### `discard(key)`343344Эти методы немедленно удаляют сообщение. Соглашение MH помечать сообщение на удаление добавлением запятой к его имени не используется.345346#### `lock()`347348#### `unlock()`349350Используются три механизма блокировки – dot-блокировка и, если доступны, `flock()` и `lockf()` системные вызовы. Для почтовых ящиков MH блокировка почтового ящика означает блокировку файла `.mh_sequences` и, только на время любых операций, которые на них влияют, блокировку отдельных файлов сообщений.351352#### `get_file(key)`353354В зависимости от платформы может быть невозможно удалить базовое сообщение, пока возвращённый файл остаётся открытым.355356#### `flush()`357358Все изменения в почтовых ящиках MH применяются немедленно, поэтому этот метод ничего не делает.359360#### `close()`361362Экземпляры [`MH`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MH) не хранят открытых файлов, поэтому этот метод эквивалентен [`unlock()`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MH.unlock).363364> **См. также**365>366> **[nmh – система обработки сообщений](https://python-all.ru/3.3/library/mailbox.html)**367>368> Домашняя страница369>370> **nmh**371>372> , обновлённой версии исходного373>374> **mh**375>376> .377>378> **[MH и nmh: электронная почта для пользователей и программистов](https://python-all.ru/3.3/library/mailbox.html)**379>380> Книга, лицензированная под GPL, о381>382> **mh**383>384> и385>386> **nmh**387>388> , с некоторой информацией о формате почтового ящика.389390### 19.4.1.4. [`Babyl`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Babyl)391392#### `class mailbox.Babyl(path, factory=None, create=True)`393394Подкласс [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) для почтовых ящиков в формате Babyl. Параметр *factory* – это вызываемый объект, который принимает файлоподобное представление сообщения (которое ведет себя так, как если бы было открыто в бинарном режиме) и возвращает пользовательское представление. Если *factory* равно `None`, то в качестве представления сообщения по умолчанию используется [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage). Если *create* равно `True`, почтовый ящик создается, если он не существует.395396Babyl – это однофайловый формат почтового ящика, используемый почтовым клиентом Rmail, входящим в состав Emacs. Начало сообщения обозначается строкой, содержащей два символа: Control-Подчёркивание (`'\037'`) и Control-L (`'\014'`). Конец сообщения обозначается началом следующего сообщения или, в случае последнего сообщения, строкой, содержащей символ Control-Подчёркивание (`'\037'`).397398Сообщения в почтовом ящике Babyl имеют два набора заголовков: исходные заголовки и так называемые видимые заголовки. Видимые заголовки обычно являются подмножеством исходных заголовков, которые были переформатированы или сокращены для большей привлекательности. Каждое сообщение в почтовом ящике Babyl также имеет сопутствующий список *меток* (коротких строк, которые записывают дополнительную информацию о сообщении), а список всех определённых пользователем меток, найденных в почтовом ящике, хранится в разделе параметров Babyl.399400Экземпляры [`Babyl`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Babyl) имеют все методы [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox), а также следующие:401402#### `get_labels()`403404Возвращает список имён всех определённых пользователем меток, используемых в почтовом ящике.405406> **Примечание**407>408> Фактические сообщения проверяются для определения того, какие метки существуют в почтовом ящике, вместо обращения к списку меток в разделе параметров Babyl, но раздел Babyl обновляется при каждом изменении почтового ящика.409410Некоторые методы [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox), реализованные в [`Babyl`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Babyl), заслуживают отдельных замечаний:411412#### `get_file(key)`413414В почтовых ящиках Babyl заголовки сообщения хранятся не подряд с телом сообщения. Чтобы создать представление, подобное файлу, заголовки и тело копируются вместе в экземпляр [`io.BytesIO`](https://python-all.ru/3.3/library/io.html#io.BytesIO), API которого идентичен API файла. В результате объект, подобный файлу, полностью независим от нижележащего почтового ящика, но не экономит память по сравнению со строковым представлением.415416#### `lock()`417418#### `unlock()`419420Используются три механизма блокировки: точечная блокировка и, если доступны, системные вызовы `flock()` и `lockf()`.421422> **См. также**423>424> **[Формат файлов Babyl версии 5](https://python-all.ru/3.3/library/mailbox.html)**425>426> Спецификация формата Babyl.427>428> **[Чтение почты с помощью Rmail](https://python-all.ru/3.3/library/mailbox.html)**429>430> Руководство по Rmail, содержащее некоторую информацию о семантике Babyl.431432### 19.4.1.5. [`MMDF`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDF)433434#### `class mailbox.MMDF(path, factory=None, create=True)`435436Подкласс [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) для почтовых ящиков в формате MMDF. Параметр *factory* – это вызываемый объект, который принимает файлоподобное представление сообщения (которое ведет себя так, как если бы было открыто в бинарном режиме) и возвращает пользовательское представление. Если *factory* равно `None`, то в качестве представления сообщения по умолчанию используется [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage). Если *create* равно `True`, почтовый ящик создается, если он не существует.437438MMDF – это формат почтового ящика в одном файле, изобретенный для Multichannel Memorandum Distribution Facility, агента пересылки почты. Каждое сообщение имеет ту же форму, что и сообщение mbox, но обрамляется до и после строками, содержащими четыре символа Control-A (`'\001'`). Как и в формате mbox, начало каждого сообщения обозначается строкой, первые пять символов которой – «From », но дополнительные вхождения «From » не преобразуются в «\>From » при сохранении сообщений, потому что дополнительные строки-разделители сообщений предотвращают ошибочный прием таких вхождений за начала последующих сообщений.439440Некоторые методы [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox), реализованные в [`MMDF`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDF), заслуживают отдельных замечаний:441442#### `get_file(key)`443444Использование файла после вызова `flush()` или `close()` на экземпляре [`MMDF`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDF) может привести к непредсказуемым результатам или вызвать исключение.445446#### `lock()`447448#### `unlock()`449450Используются три механизма блокировки: точечная блокировка и, если доступны, системные вызовы `flock()` и `lockf()`.451452> **См. также**453>454> **[страница руководства mmdf из tin](https://python-all.ru/3.3/library/mailbox.html)**455>456> Спецификация формата MMDF из документации tin, программы для чтения новостей.457>458> **[MMDF](https://python-all.ru/3.3/library/mailbox.html)**459>460> Статья в Википедии, описывающая Multichannel Memorandum Distribution Facility.461462## 19.4.2. [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message) объекты463464#### `class mailbox.Message(message=None)`465466Подкласс [`Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message) из модуля [`email.message`](https://python-all.ru/3.3/library/email.message.html#module-email.message). Подклассы [`mailbox.Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message) добавляют состояние и поведение, специфичные для формата почтового ящика.467468Если параметр *message* опущен, новый экземпляр создается в состоянии по умолчанию, пустом. Если *message* является экземпляром [`email.message.Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message), его содержимое копируется; кроме того, любая специфичная для формата информация преобразуется, насколько это возможно, если *message* является экземпляром [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message). Если *message* является строкой, байтовой строкой или файлом, он должен содержать сообщение, совместимое с [**RFC 2822**](https://python-all.ru/3.3/library/mailbox.html), которое считывается и разбирается. Файлы должны быть открыты в бинарном режиме, но текстовые файлы принимаются для обратной совместимости.469470Формат-специфичные состояния и поведение, предоставляемые подклассами, различаются, но в целом поддерживаются только те свойства, которые не привязаны к конкретному почтовому ящику (хотя, предположительно, эти свойства специфичны для конкретного формата почтового ящика). Например, смещения в файлах для однофайловых форматов почтовых ящиков и имена файлов для форматов на основе каталогов не сохраняются, так как они применимы только к исходному почтовому ящику. Но такие состояния, как было ли сообщение прочитано пользователем или помечено как важное, сохраняются, поскольку они относятся к самому сообщению.471472Нет требования, чтобы экземпляры [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message) использовались для представления сообщений, полученных с помощью экземпляров [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox). В некоторых ситуациях время и память, необходимые для создания представлений [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message), могут быть неприемлемыми. Для таких ситуаций экземпляры [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) также предлагают строковые и файлоподобные представления, а пользовательская фабрика сообщений может быть указана при инициализации экземпляра [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox).473474### 19.4.2.1. [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage)475476#### `class mailbox.MaildirMessage(message=None)`477478Сообщение с поведением, специфичным для Maildir. Параметр *message* имеет то же значение, что и в конструкторе [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message).479480Обычно почтовый клиент перемещает все сообщения из подкаталога `new` в подкаталог `cur` после первого открытия и закрытия почтового ящика пользователем, отмечая, что сообщения устарели, независимо от того, были ли они прочитаны. Каждое сообщение в `cur` имеет раздел «info», добавленный к его имени файла, для хранения информации о его состоянии. (Некоторые почтовые программы могут также добавлять раздел «info» к сообщениям в `new`.) Раздел «info» может принимать одну из двух форм: он может содержать «2,» с последующим списком стандартизированных флагов (например, «2,FR») или может содержать «1,» с последующей так называемой экспериментальной информацией. Стандартные флаги для сообщений Maildir следующие:481482| Флаг | Значение | Пояснение |483| --- | --- | --- |484| D | Черновик | В процессе составления |485| F | Помечено | Помечено как важное |486| P | Передан | Переслано, отправлено повторно или возвращено |487| R | Отвечено | Получен ответ |488| S | Просмотрено | Прочитано |489| T | Удалено | Помечено для последующего удаления |490491Экземпляры [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage) предоставляют следующие методы:492493#### `get_subdir()`494495Возвращает либо «new» (если сообщение должно храниться в подкаталоге `new`), либо «cur» (если сообщение должно храниться в подкаталоге `cur`).496497> **Примечание**498>499> Сообщение обычно перемещается из `new` в `cur` после обращения к его почтовому ящику, независимо от того, было ли сообщение прочитано. Сообщение `msg` считается прочитанным, если `"S" in msg.get_flags()` равно `True`.500501#### `set_subdir(subdir)`502503Устанавливает подкаталог, в котором должно храниться сообщение. Параметр *subdir* должен быть либо «new», либо «cur».504505#### `get_flags()`506507Возвращает строку с указанием установленных в данный момент флагов. Если сообщение соответствует стандартному формату Maildir, результатом будет конкатенация в алфавитном порядке не более одного вхождения каждого из `'D'`, `'F'`, `'P'`, `'R'`, `'S'` и `'T'`. Пустая строка возвращается, если флаги не установлены или если «info» содержит экспериментальную семантику.508509#### `set_flags(flags)`510511Устанавливает флаги, указанные *flags*, и сбрасывает все остальные.512513#### `add_flag(flag)`514515Устанавливает флаг(и), указанные *flag*, не изменяя остальные флаги. Чтобы добавить более одного флага за раз, *flag* может быть строкой из более чем одного символа. Текущий «info» перезаписывается, независимо от того, содержит ли он экспериментальную информацию вместо флагов.516517#### `remove_flag(flag)`518519Сбрасывает флаг(и), указанные в *flag*, не изменяя другие флаги. Чтобы удалить несколько флагов за раз, *flag* может быть строкой из более чем одного символа. Если «info» содержит экспериментальную информацию, а не флаги, текущий «info» не изменяется.520521#### `get_date()`522523Возвращает дату доставки сообщения в виде числа с плавающей запятой, представляющего количество секунд с начала эпохи.524525#### `set_date(date)`526527Устанавливает дату доставки сообщения в *date*, число с плавающей запятой, представляющее количество секунд с начала эпохи.528529#### `get_info()`530531Возвращает строку, содержащую «info» для сообщения. Это полезно для доступа к экспериментальному «info» и его изменения (т.е. не являющегося списком флагов).532533#### `set_info(info)`534535Устанавливает «info» в *info*, которое должно быть строкой.536537Когда экземпляр [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage) создается на основе экземпляра [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) или [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage), заголовки *Status* и *X-Status* опускаются, и выполняются следующие преобразования:538539| Результирующее состояние | [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) или [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage) состояние |540| --- | --- |541| Подкаталог «cur» | Флаг O |542| Флаг F | Флаг F |543| Флаг R | Флаг A |544| Флаг S | Флаг R |545| Флаг T | Флаг D |546547Когда экземпляр [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage) создается на основе экземпляра [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage), выполняются следующие преобразования:548549| Результирующее состояние | [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage) состояние |550| --- | --- |551| Подкаталог «cur» | последовательность «unseen» |552| подкаталог «cur» и флаг S | нет последовательности «unseen» |553| Флаг F | последовательность «flagged» |554| Флаг R | последовательность «replied» |555556Когда экземпляр [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage) создается на основе экземпляра [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage), выполняются следующие преобразования:557558| Результирующее состояние | [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage) состояние |559| --- | --- |560| Подкаталог «cur» | метка «unseen» |561| подкаталог «cur» и флаг S | нет метки «unseen» |562| Флаг P | метка «forwarded» или «resent» |563| Флаг R | метка «отвечено» |564| Флаг T | метка «удалено» |565566### 19.4.2.2. [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage)567568#### `class mailbox.mboxMessage(message=None)`569570Сообщение с поведением, специфичным для mbox. Параметр *message* имеет то же значение, что и в конструкторе [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message).571572Сообщения в почтовом ящике mbox хранятся вместе в одном файле. Адрес отправителя (envelope address) и время доставки обычно хранятся в строке, начинающейся с «From », которая используется для обозначения начала сообщения, хотя точный формат этих данных сильно различается в разных реализациях mbox. Флаги, указывающие на состояние сообщения, такие как прочитано или помечено как важное, обычно хранятся в заголовках *Status* и *X-Status*.573574Обычные флаги для сообщений mbox:575576| Флаг | Значение | Пояснение |577| --- | --- | --- |578| R | Прочитано | Прочитано |579| O | Старое | Ранее обнаружено почтовым клиентом |580| D | Удалено | Помечено для последующего удаления |581| F | Помечено | Помечено как важное |582| A | Отвечено | Получен ответ |583584Флаги «R» и «O» хранятся в заголовке *Status*, а флаги «D», «F» и «A» – в заголовке *X-Status*. Флаги и заголовки обычно располагаются в указанном порядке.585586Экземпляры [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) предоставляют следующие методы:587588#### `get_from()`589590Возвращает строку, представляющую строку «From », отмечающую начало сообщения в почтовом ящике mbox. Начальная «From » и конечный символ новой строки исключаются.591592#### `set_from(from_, time_=None)`593594Устанавливает строку «From » в значение *from\_*, которое должно быть указано без начальной строки «From » и завершающего символа новой строки. Для удобства можно указать *time\_*, который будет соответствующим образом отформатирован и добавлен к *from\_*. Если *time\_* указан, он должен быть экземпляром [`time.struct_time`](https://python-all.ru/3.3/library/time.html#time.struct_time), кортежем, пригодным для передачи в [`time.strftime()`](https://python-all.ru/3.3/library/time.html#time.strftime), или `True` (для использования [`time.gmtime()`](https://python-all.ru/3.3/library/time.html#time.gmtime)).595596#### `get_flags()`597598Возвращает строку, указывающую флаги, которые в данный момент установлены. Если сообщение соответствует обычному формату, результатом является конкатенация в следующем порядке: ноль или одно вхождение каждого из `'R'`, `'O'`, `'D'`, `'F'` и `'A'`.599600#### `set_flags(flags)`601602Устанавливает флаги, указанные параметром *flags*, и сбрасывает все остальные. Параметр *flags* должен быть конкатенацией в любом порядке нуля или более вхождений каждого из `'R'`, `'O'`, `'D'`, `'F'` и `'A'`.603604#### `add_flag(flag)`605606Устанавливает флаг(и), указанные в *flag*, не изменяя другие флаги. Чтобы добавить более одного флага за раз, *flag* может быть строкой из более чем одного символа.607608#### `remove_flag(flag)`609610Снимает флаг(и), указанные в *flag*, не изменяя другие флаги. Чтобы снять несколько флагов одновременно, *flag* может быть строкой из более чем одного символа.611612Когда экземпляр [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) создается на основе экземпляра [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage), строка «From » генерируется на основе даты доставки экземпляра [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage), и выполняются следующие преобразования:613614| Результирующее состояние | [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage) состояние |615| --- | --- |616| Флаг R | Флаг S |617| Флаг O | Подкаталог «cur» |618| Флаг D | Флаг T |619| Флаг F | Флаг F |620| Флаг A | Флаг R |621622Когда экземпляр [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) создаётся на основе экземпляра [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage), выполняются следующие преобразования:623624| Результирующее состояние | [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage) состояние |625| --- | --- |626| Флаг R и флаг O | нет последовательности «unseen» |627| Флаг O | последовательность «unseen» |628| Флаг F | последовательность «flagged» |629| Флаг A | последовательность «replied» |630631Когда экземпляр [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) создаётся на основе экземпляра [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage), выполняются следующие преобразования:632633| Результирующее состояние | [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage) состояние |634| --- | --- |635| Флаг R и флаг O | нет метки «unseen» |636| Флаг O | метка «unseen» |637| Флаг D | метка «удалено» |638| Флаг A | метка «отвечено» |639640Когда экземпляр [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message) создаётся на основе экземпляра [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage) , строка «From » копируется, и все флаги напрямую соответствуют:641642| Результирующее состояние | состояние [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage) |643| --- | --- |644| Флаг R | Флаг R |645| Флаг O | Флаг O |646| Флаг D | Флаг D |647| Флаг F | Флаг F |648| Флаг A | Флаг A |649650### 19.4.2.3. [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage)651652#### `class mailbox.MHMessage(message=None)`653654Сообщение с поведением, специфичным для MH. Параметр *message* имеет тот же смысл, что и в конструкторе [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message).655656Сообщения MH не поддерживают метки и флаги в традиционном понимании, но поддерживают последовательности – логические группировки произвольных сообщений. Некоторые почтовые программы (хотя не стандартные **mh** и **nmh**) используют последовательности примерно так же, как флаги используются в других форматах:657658| Последовательность | Пояснение |659| --- | --- |660| непрочитанное | Не прочитано, но ранее обнаружено почтовым клиентом (MUA) |661| отвечено | Получен ответ |662| помечено | Помечено как важное |663664Экземпляры [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage) предоставляют следующие методы:665666#### `get_sequences()`667668Возвращает список имен последовательностей, которые включают это сообщение.669670#### `set_sequences(sequences)`671672Устанавливает список последовательностей, которые включают это сообщение.673674#### `add_sequence(sequence)`675676Добавляет *sequence* в список последовательностей, которые включают это сообщение.677678#### `remove_sequence(sequence)`679680Удаляет *sequence* из списка последовательностей, которые включают это сообщение.681682Когда экземпляр [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage) создаётся на основе экземпляра [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage), выполняются следующие преобразования:683684| Результирующее состояние | [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage) состояние |685| --- | --- |686| последовательность «unseen» | нет флага S |687| последовательность «replied» | Флаг R |688| последовательность «flagged» | Флаг F |689690Когда экземпляр [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage) создаётся на основе экземпляра [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) или [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage), заголовки *Status* и *X-Status* опускаются, и выполняются следующие преобразования:691692| Результирующее состояние | [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) или [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage) состояние |693| --- | --- |694| последовательность «unseen» | нет флага R |695| последовательность «replied» | Флаг A |696| последовательность «flagged» | Флаг F |697698Когда экземпляр [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage) создаётся на основе экземпляра [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage), выполняются следующие преобразования:699700| Результирующее состояние | [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage) состояние |701| --- | --- |702| последовательность «unseen» | метка «unseen» |703| последовательность «replied» | метка «отвечено» |704705### 19.4.2.4. [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage)706707#### `class mailbox.BabylMessage(message=None)`708709Сообщение с поведением, специфичным для Babyl. Параметр *message* имеет тот же смысл, что и в конструкторе [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message).710711Некоторые метки сообщений, называемые *attributes*, по соглашению имеют специальное значение. Атрибуты следующие:712713| Метка | Пояснение |714| --- | --- |715| непрочитанное | Не прочитано, но ранее обнаружено почтовым клиентом (MUA) |716| удалено | Помечено для последующего удаления |717| архивировано | Скопировано в другой файл или почтовый ящик |718| отвечено | Получен ответ |719| переслано | Переслано |720| изменено | Изменено пользователем |721| переотправлено | Отправлено повторно |722723По умолчанию Rmail отображает только видимые заголовки. Класс [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage) , однако, использует оригинальные заголовки, поскольку они более полны. К видимым заголовкам можно обратиться явно при желании.724725Экземпляры [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage) предоставляют следующие методы:726727#### `get_labels()`728729Возвращает список меток сообщения.730731#### `set_labels(labels)`732733Устанавливает список меток сообщения равным *labels*.734735#### `add_label(label)`736737Добавляет метку *label* в список меток сообщения.738739#### `remove_label(label)`740741Удаляет метку *label* из списка меток сообщения.742743#### `get_visible()`744745Возвращает экземпляр [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message), заголовки которого являются видимыми заголовками сообщения, а тело пусто.746747#### `set_visible(visible)`748749Устанавливает видимые заголовки сообщения такими же, как заголовки в *message*. Параметр *visible* должен быть экземпляром [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message), экземпляром [`email.message.Message`](https://python-all.ru/3.3/library/email.message.html#email.message.Message), строкой или объектом, подобным файлу (который должен быть открыт в текстовом режиме).750751#### `update_visible()`752753Когда изменяются исходные заголовки экземпляра [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage), видимые заголовки не изменяются автоматически для соответствия. Этот метод обновляет видимые заголовки следующим образом: каждый видимый заголовок, имеющий соответствующий исходный заголовок, устанавливается в значение исходного заголовка; каждый видимый заголовок, не имеющий соответствующего исходного заголовка, удаляется; а любые из *Date*, *From*, *Reply-To*, *To*, *CC* и *Subject*, которые присутствуют в исходных заголовках, но отсутствуют среди видимых, добавляются к видимым заголовкам.754755Когда экземпляр [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage) создаётся на основе экземпляра [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage), выполняются следующие преобразования:756757| Результирующее состояние | [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage) состояние |758| --- | --- |759| метка «unseen» | нет флага S |760| метка «удалено» | Флаг T |761| метка «отвечено» | Флаг R |762| Метка «forwarded» | Флаг P |763764Когда экземпляр [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage) создаётся на основе экземпляра [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) или [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage), заголовки *Status* и *X-Status* опускаются и выполняются следующие преобразования:765766| Результирующее состояние | [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) или [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage) состояние |767| --- | --- |768| метка «unseen» | нет флага R |769| метка «удалено» | Флаг D |770| метка «отвечено» | Флаг A |771772Когда экземпляр [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage) создаётся на основе экземпляра [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage), выполняются следующие преобразования:773774| Результирующее состояние | [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage) состояние |775| --- | --- |776| метка «unseen» | последовательность «unseen» |777| метка «отвечено» | последовательность «replied» |778779### 19.4.2.5. [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage)780781#### `class mailbox.MMDFMessage(message=None)`782783Сообщение с поведением, специфичным для MMDF. Параметр *message* имеет то же значение, что и в конструкторе [`Message`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Message).784785Как и сообщения в почтовом ящике mbox, сообщения MMDF хранятся с адресом отправителя и датой доставки в начальной строке, начинающейся с «From ». Аналогично, флаги, указывающие состояние сообщения, обычно хранятся в заголовках *Status* и *X-Status*.786787Стандартные флаги для сообщений MMDF совпадают с флагами сообщений mbox и перечислены ниже:788789| Флаг | Значение | Пояснение |790| --- | --- | --- |791| R | Прочитано | Прочитано |792| O | Старое | Ранее обнаружено почтовым клиентом |793| D | Удалено | Помечено для последующего удаления |794| F | Помечено | Помечено как важное |795| A | Отвечено | Получен ответ |796797Флаги «R» и «O» хранятся в заголовке *Status*, а флаги «D», «F» и «A» – в заголовке *X-Status*. Флаги и заголовки обычно располагаются в указанном порядке.798799Экземпляры [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage) предоставляют следующие методы, идентичные методам, предоставляемым [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage):800801#### `get_from()`802803Возвращает строку, представляющую строку «From », отмечающую начало сообщения в почтовом ящике mbox. Начальная «From » и конечный символ новой строки исключаются.804805#### `set_from(from_, time_=None)`806807Устанавливает строку «From » в значение *from\_*, которое должно быть указано без начальной строки «From » и завершающего символа новой строки. Для удобства можно указать *time\_*, который будет соответствующим образом отформатирован и добавлен к *from\_*. Если *time\_* указан, он должен быть экземпляром [`time.struct_time`](https://python-all.ru/3.3/library/time.html#time.struct_time), кортежем, пригодным для передачи в [`time.strftime()`](https://python-all.ru/3.3/library/time.html#time.strftime), или `True` (для использования [`time.gmtime()`](https://python-all.ru/3.3/library/time.html#time.gmtime)).808809#### `get_flags()`810811Возвращает строку, указывающую флаги, которые в данный момент установлены. Если сообщение соответствует обычному формату, результатом является конкатенация в следующем порядке: ноль или одно вхождение каждого из `'R'`, `'O'`, `'D'`, `'F'` и `'A'`.812813#### `set_flags(flags)`814815Устанавливает флаги, указанные параметром *flags*, и сбрасывает все остальные. Параметр *flags* должен быть конкатенацией в любом порядке нуля или более вхождений каждого из `'R'`, `'O'`, `'D'`, `'F'` и `'A'`.816817#### `add_flag(flag)`818819Устанавливает флаг(и), указанные в *flag*, не изменяя другие флаги. Чтобы добавить более одного флага за раз, *flag* может быть строкой из более чем одного символа.820821#### `remove_flag(flag)`822823Снимает флаг(и), указанные в *flag*, не изменяя другие флаги. Чтобы снять несколько флагов одновременно, *flag* может быть строкой из более чем одного символа.824825Когда экземпляр [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage) создаётся на основе экземпляра [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage), строка «From » генерируется на основе даты доставки экземпляра [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage), и выполняются следующие преобразования:826827| Результирующее состояние | [`MaildirMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MaildirMessage) состояние |828| --- | --- |829| Флаг R | Флаг S |830| Флаг O | Подкаталог «cur» |831| Флаг D | Флаг T |832| Флаг F | Флаг F |833| Флаг A | Флаг R |834835Когда экземпляр [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage) создаётся на основе экземпляра [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage), выполняются следующие преобразования:836837| Результирующее состояние | [`MHMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MHMessage) состояние |838| --- | --- |839| Флаг R и флаг O | нет последовательности «unseen» |840| Флаг O | последовательность «unseen» |841| Флаг F | последовательность «flagged» |842| Флаг A | последовательность «replied» |843844Когда экземпляр [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage) создаётся на основе экземпляра [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage), выполняются следующие преобразования:845846| Результирующее состояние | [`BabylMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.BabylMessage) состояние |847| --- | --- |848| Флаг R и флаг O | нет метки «unseen» |849| Флаг O | метка «unseen» |850| Флаг D | метка «удалено» |851| Флаг A | метка «отвечено» |852853Когда экземпляр [`MMDFMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MMDFMessage) создаётся на основе экземпляра [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage), строка «From » копируется и все флаги напрямую соответствуют:854855| Результирующее состояние | [`mboxMessage`](https://python-all.ru/3.3/library/mailbox.html#mailbox.mboxMessage) состояние |856| --- | --- |857| Флаг R | Флаг R |858| Флаг O | Флаг O |859| Флаг D | Флаг D |860| Флаг F | Флаг F |861| Флаг A | Флаг A |862863## 19.4.3. Исключения864865Следующие классы исключений определены в модуле [`mailbox`](https://python-all.ru/3.3/library/mailbox.html#module-mailbox):866867#### `exception mailbox.Error`868869Базовый класс для всех остальных исключений, специфичных для модуля.870871#### `exception mailbox.NoSuchMailboxError`872873Возникает, когда ожидается почтовый ящик, но он не найден, например, при создании экземпляра подкласса [`Mailbox`](https://python-all.ru/3.3/library/mailbox.html#mailbox.Mailbox) с несуществующим путём (и с параметром *create*, установленным в `False`), или при открытии несуществующей папки.874875#### `exception mailbox.NotEmptyError`876877Вызывается, когда почтовый ящик не пуст, но ожидается пустым, например, при удалении папки, содержащей сообщения.878879#### `exception mailbox.ExternalClashError`880881Возникает, когда не зависящее от программы условие, связанное с почтовым ящиком, не позволяет продолжить работу, например, когда не удаётся получить блокировку, которая уже удерживается другой программой, или когда сгенерированное уникальное имя файла уже существует.882883#### `exception mailbox.FormatError`884885Возникает, когда данные в файле не могут быть разобраны, например, когда экземпляр [`MH`](https://python-all.ru/3.3/library/mailbox.html#mailbox.MH) пытается прочитать повреждённый файл `.mh_sequences`.886887## 19.4.4. Примеры888889Простой пример вывода тем всех сообщений в почтовом ящике, которые кажутся интересными:890891```python892import mailbox893for message in mailbox.mbox('~/mbox'):894    subject = message['subject']       # Может быть None.895    if subject and 'python' in subject.lower():896        print(subject)897```898899Чтобы скопировать все письма из почтового ящика Babyl в почтовый ящик MH, преобразуя всю форматно-специфичную информацию, которую можно преобразовать:900901```python902import mailbox903destination = mailbox.MH('~/Mail')904destination.lock()905for message in mailbox.Babyl('~/RMAIL'):906    destination.add(mailbox.MHMessage(message))907destination.flush()908destination.unlock()909```910911Этот пример сортирует письма из нескольких списков рассылки по разным почтовым ящикам, стараясь избежать повреждения писем из-за одновременного изменения другими программами, потери писем из-за прерывания программы или преждевременного завершения из-за повреждённых сообщений в почтовом ящике:912913```python914import mailbox915import email.errors916917list_names = ('python-list', 'python-dev', 'python-bugs')918919boxes = {name: mailbox.mbox('~/email/%s' % name) for name in list_names}920inbox = mailbox.Maildir('~/Maildir', factory=None)921922for key in inbox.iterkeys():923    try:924        message = inbox[key]925    except email.errors.MessageParseError:926        continue                # Сообщение повреждено. Просто оставьте его.927928    for name in list_names:929        list_id = message['list-id']930        if list_id and name in list_id:931            # Получить почтовый ящик для использования.932            box = boxes[name]933934            # Записать копию на диск перед удалением оригинала.935            # Если произошёл сбой, возможно дублирование сообщения, но936            # это лучше, чем полная потеря сообщения.937            box.lock()938            box.add(message)939            box.flush()940            box.unlock()941942            # Удалить исходное сообщение943            inbox.lock()944            inbox.discard(key)945            inbox.flush()946            inbox.unlock()947            break               # Целевой получатель найден, поиск прекращён.948949for box in boxes.itervalues():950    box.close()951```952