mailbox.md
1> **Источник:** https://python-all.ru/3.9/library/mailbox.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [`mailbox`](https://python-all.ru/3.9/library/mailbox.html#module-mailbox) – Управление почтовыми ящиками в различных форматах89**Исходный код:** [Lib/mailbox.py](https://python-all.ru/src/3.9/Lib/mailbox.py)1011---1213Этот модуль определяет два класса: [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) и [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message) для доступа к почтовым ящикам на диске и управления ими, а также для работы с содержащимися в них сообщениями. [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) предоставляет словареподобное отображение ключей на сообщения. [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message) расширяет класс [`Message`](https://python-all.ru/3.9/library/email.compat32-message.html#email.message.Message) из модуля [`email.message`](https://python-all.ru/3.9/library/email.message.html#module-email.message), добавляя формат-специфичное состояние и поведение. Поддерживаемые форматы почтовых ящиков: Maildir, mbox, MH, Babyl и MMDF.1415> **См. также**16>17> **Модуль [`email`](https://python-all.ru/3.9/library/email.html#module-email)**18>19> Представление сообщений и управление ими.2021## [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) объекты2223#### `class mailbox.Mailbox`2425Почтовый ящик, который можно просматривать и изменять.2627Класс [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) определяет интерфейс и не предназначен для создания экземпляров. Вместо этого следует наследовать формат-специфичные подклассы от [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox), а код должен создавать экземпляры конкретного подкласса.2829Интерфейс [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) напоминает словарь: небольшие ключи соответствуют сообщениям. Ключи выдаются экземпляром [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox), с которым они будут использоваться, и имеют смысл только для этого экземпляра [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox). Ключ продолжает идентифицировать сообщение, даже если соответствующее сообщение изменяется, например, заменяется другим сообщением.3031Сообщения можно добавлять в экземпляр [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) с помощью метода [`add()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.add) (подобного set) и удалять с помощью инструкции `del` или методов [`remove()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.remove) и [`discard()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.discard) (также подобных set).3233Семантика интерфейса [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) отличается от семантики словаря в некоторых важных аспектах. При каждом запросе сообщения на основе текущего состояния почтового ящика создаётся новое представление (обычно экземпляр [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message)). Аналогично, при добавлении сообщения в экземпляр [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) содержимое переданного представления сообщения копируется. Ни в одном из случаев экземпляр [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) не сохраняет ссылку на представление сообщения.3435Итератор по умолчанию [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) перебирает представления сообщений, а не ключи, как это делает итератор словаря по умолчанию. Кроме того, изменение почтового ящика во время итерации безопасно и хорошо определено. Сообщения, добавленные в почтовый ящик после создания итератора, не будут видны итератору. Сообщения, удалённые из почтового ящика до того, как итератор их вернёт, будут молча пропущены, хотя использование ключа из итератора может привести к исключению [`KeyError`](https://python-all.ru/3.9/library/exceptions.html#KeyError), если соответствующее сообщение будет впоследствии удалено.3637> **Предупреждение**38>39> Будьте предельно осторожны при изменении почтовых ящиков, которые могут одновременно изменяться другим процессом. Самый безопасный формат почтового ящика для таких задач – Maildir; старайтесь избегать использования однофайловых форматов, таких как mbox, для одновременной записи. Если вы изменяете почтовый ящик, вы *должны* заблокировать его, вызвав методы [`lock()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.lock) и [`unlock()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.unlock) *перед* чтением любых сообщений в файле или внесением каких-либо изменений путём добавления или удаления сообщения. Несоблюдение блокировки почтового ящика чревато потерей сообщений или повреждением всего почтового ящика.4041Экземпляры [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) имеют следующие методы:4243#### `add(message)`4445Добавляет *сообщение* в почтовый ящик и возвращает ключ, который был ему присвоен.4647Параметр *message* может быть экземпляром [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message), экземпляром [`email.message.Message`](https://python-all.ru/3.9/library/email.compat32-message.html#email.message.Message), строкой, байтовой строкой или файлоподобным объектом (который должен быть открыт в двоичном режиме). Если *message* является экземпляром соответствующего формат-специфичного подкласса [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message) (например, если это экземпляр [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage), а это экземпляр [`mbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mbox)), используется его формат-специфичная информация. В противном случае используются разумные значения по умолчанию для формат-специфичной информации.4849Изменено в версии 3.2: Добавлена поддержка двоичного ввода.5051#### `remove(key)`5253#### `__delitem__(key)`5455#### `discard(key)`5657Удаляет сообщение, соответствующее *ключу*, из почтового ящика.5859Если такого сообщения не существует, возникает исключение [`KeyError`](https://python-all.ru/3.9/library/exceptions.html#KeyError), если метод был вызван как [`remove()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.remove) или [`__delitem__()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.__delitem__), но исключение не возникает, если метод был вызван как [`discard()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.discard). Поведение [`discard()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.discard) может быть предпочтительнее, если базовый формат почтового ящика поддерживает одновременное изменение другими процессами.6061#### `__setitem__(key, message)`6263Заменяет сообщение, соответствующее *ключу*, на *сообщение*. Возникает исключение [`KeyError`](https://python-all.ru/3.9/library/exceptions.html#KeyError), если *ключу* ещё не соответствует ни одно сообщение.6465Как и в случае с [`add()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.add), параметр *message* может быть экземпляром [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message), экземпляром [`email.message.Message`](https://python-all.ru/3.9/library/email.compat32-message.html#email.message.Message), строкой, байтовой строкой или файлоподобным объектом (который должен быть открыт в двоичном режиме). Если *message* является экземпляром соответствующего формат-специфичного подкласса [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message) (например, если это экземпляр [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage), а это экземпляр [`mbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mbox)), используется его формат-специфичная информация. В противном случае формат-специфичная информация сообщения, которое в данный момент соответствует *ключу*, остаётся неизменной.6667#### `iterkeys()`6869#### `keys()`7071Возвращает итератор по всем ключам, если вызван как [`iterkeys()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.iterkeys), или возвращает список ключей, если вызван как [`keys()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.keys).7273#### `itervalues()`7475#### `__iter__()`7677#### `values()`7879Возвращает итератор по представлениям всех сообщений, если вызван как [`itervalues()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.itervalues) или [`__iter__()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.__iter__), или возвращает список таких представлений, если вызван как [`values()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.values). Сообщения представлены в виде экземпляров соответствующего подкласса [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message), зависящего от формата, если только при инициализации экземпляра [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) не была указана пользовательская фабрика сообщений.8081> **Примечание**82>83> Поведение [`__iter__()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.__iter__) отличается от поведения словарей, которые перебирают ключи.8485#### `iteritems()`8687#### `items()`8889Возвращает итератор по парам (*key*, *message*), где *key* – ключ, а *message* – представление сообщения, если вызван как [`iteritems()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.iteritems), или возвращает список таких пар, если вызван как [`items()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.items). Сообщения представлены в виде экземпляров соответствующего подкласса [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message), зависящего от формата, если только при инициализации экземпляра [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) не была указана пользовательская фабрика сообщений.9091#### `get(key, default=None)`9293#### `__getitem__(key)`9495Возвращает представление сообщения, соответствующего *ключу*. Если такого сообщения нет, *default* возвращается, если метод был вызван как [`get()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.get), и вызывается исключение [`KeyError`](https://python-all.ru/3.9/library/exceptions.html#KeyError), если метод был вызван как [`__getitem__()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.__getitem__). Сообщение представляется в виде экземпляра соответствующего подкласса [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message), если только при инициализации экземпляра [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) не была указана пользовательская фабрика сообщений.9697#### `get_message(key)`9899Возвращает представление сообщения, соответствующего *ключу*, в виде экземпляра соответствующего подкласса [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message), или вызывает исключение [`KeyError`](https://python-all.ru/3.9/library/exceptions.html#KeyError), если такого сообщения нет.100101#### `get_bytes(key)`102103Возвращает байтовое представление сообщения, соответствующего *ключу*, или вызывает исключение [`KeyError`](https://python-all.ru/3.9/library/exceptions.html#KeyError), если такого сообщения нет.104105Новое в версии 3.2.106107#### `get_string(key)`108109Возвращает строковое представление сообщения, соответствующего *ключу*, или вызывает исключение [`KeyError`](https://python-all.ru/3.9/library/exceptions.html#KeyError), если такого сообщения нет. Сообщение обрабатывается через [`email.message.Message`](https://python-all.ru/3.9/library/email.compat32-message.html#email.message.Message) для преобразования в 7-битное чистое представление.110111#### `get_file(key)`112113Возвращает файлоподобное представление сообщения, соответствующего ключу *key*, или вызывает исключение [`KeyError`](https://python-all.ru/3.9/library/exceptions.html#KeyError), если такого сообщения не существует. Файлоподобный объект ведёт себя так, как если бы он был открыт в двоичном режиме. Этот файл следует закрыть, когда он больше не нужен.114115Изменено в версии 3.2: Файловый объект на самом деле является двоичным файлом; ранее он некорректно возвращался в текстовом режиме. Кроме того, файлоподобный объект теперь поддерживает протокол управления контекстом: для автоматического закрытия можно использовать оператор [`with`](https://python-all.ru/3.9/reference/compound_stmts.html#with).116117> **Примечание**118>119> В отличие от других представлений сообщений, файлоподобные представления не обязательно независимы от экземпляра [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox), который их создал, или от базового почтового ящика. Более подробная документация предоставляется каждым подклассом.120121#### `__contains__(key)`122123Возвращает `True`, если *ключ* соответствует сообщению, и `False` в противном случае.124125#### `__len__()`126127Возвращает количество сообщений в почтовом ящике.128129#### `clear()`130131Удаляет все сообщения из почтового ящика.132133#### `pop(key, default=None)`134135Возвращает представление сообщения, соответствующего *ключу*, и удаляет сообщение. Если такого сообщения нет, возвращает *default*. Сообщение представляется в виде экземпляра соответствующего подкласса [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message), если только при инициализации экземпляра [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) не была указана пользовательская фабрика сообщений.136137#### `popitem()`138139Возвращает произвольную пару (*ключ*, *сообщение*), где *ключ* – это ключ, а *сообщение* – представление сообщения, и удаляет соответствующее сообщение. Если почтовый ящик пуст, вызывает исключение [`KeyError`](https://python-all.ru/3.9/library/exceptions.html#KeyError). Сообщение представляется в виде экземпляра соответствующего подкласса [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message), если только при инициализации экземпляра [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) не была указана пользовательская фабрика сообщений.140141#### `update(arg)`142143Параметр *arg* должен быть отображением *ключ* → *сообщение* или итерируемым объектом из пар (*ключ*, *сообщение*). Обновляет почтовый ящик так, что для каждой заданной пары *ключ* и *сообщение* сообщение, соответствующее *ключу*, устанавливается в *сообщение* как если бы с помощью [`__setitem__()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.__setitem__). Как и в случае с [`__setitem__()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.__setitem__), каждый *ключ* уже должен соответствовать сообщению в почтовом ящике, иначе будет вызвано исключение [`KeyError`](https://python-all.ru/3.9/library/exceptions.html#KeyError), поэтому в общем случае неправильно, чтобы *arg* был экземпляром [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox).144145> **Примечание**146>147> В отличие от словарей, именованные аргументы не поддерживаются.148149#### `flush()`150151Записывает все ожидающие изменения в файловую систему. Для некоторых подклассов [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) изменения всегда записываются сразу, и [`flush()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox.flush) ничего не делает, но всё же стоит выработать привычку вызывать этот метод.152153#### `lock()`154155Устанавливает исключительную рекомендательную блокировку на почтовый ящик, чтобы другие процессы знали, что его не следует изменять. Если блокировка недоступна, возбуждается исключение [`ExternalClashError`](https://python-all.ru/3.9/library/mailbox.html#mailbox.ExternalClashError). Конкретные механизмы блокировки зависят от формата почтового ящика. Перед любыми изменениями содержимого следует *всегда* блокировать почтовый ящик.156157#### `unlock()`158159Освобождает блокировку почтового ящика, если она установлена.160161#### `close()`162163Сбрасывает почтовый ящик, при необходимости снимает блокировку и закрывает все открытые файлы. Для некоторых подклассов [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) этот метод ничего не делает.164165### [`Maildir`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Maildir)166167#### `class mailbox.Maildir(dirname, factory=None, create=True)`168169Подкласс [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) для почтовых ящиков в формате Maildir. Параметр *factory* – это вызываемый объект, который принимает файлоподобное представление сообщения (ведущее себя как открытое в бинарном режиме) и возвращает пользовательское представление. Если *factory* равно `None`, в качестве представления сообщения по умолчанию используется [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage). Если *create* равно `True`, почтовый ящик создаётся, если он не существует.170171Если *create* равно `True` и путь *dirname* существует, он будет рассматриваться как существующий maildir без попытки проверки структуры его каталогов.172173По историческим причинам *dirname* назван так, а не *path*.174175Maildir – это почтовый формат на основе каталогов, разработанный для агента передачи почты qmail и ныне широко поддерживаемый другими программами. Сообщения в почтовом ящике Maildir хранятся в отдельных файлах в общей структуре каталогов. Такая архитектура позволяет нескольким независимым программам получать доступ и изменять почтовые ящики Maildir без повреждения данных, поэтому файловая блокировка не требуется.176177Почтовые ящики Maildir содержат три подкаталога: `tmp`, `new` и `cur`. Сообщения создаются в подкаталоге `tmp`, а затем перемещаются в подкаталог `new` для завершения доставки. После этого почтовый клиент может переместить сообщение в подкаталог `cur` и сохранить информацию о состоянии сообщения в специальном разделе «info», добавляемом к его имени файла.178179Также поддерживаются папки в стиле, введённом агентом передачи почты Courier. Любой подкаталог основного почтового ящика считается папкой, если первым символом в его имени является `'.'`. Имена папок представляются как [`Maildir`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Maildir) без ведущего `'.'`. Каждая папка сама является почтовым ящиком Maildir, но не должна содержать другие папки. Вместо этого логическая вложенность указывается с помощью `'.'` для разделения уровней, например, «Archived.2005.07».180181> **Примечание**182>183> Спецификация Maildir требует использования двоеточия (`':'`) в некоторых именах файлов сообщений. Однако некоторые операционные системы не допускают этот символ в именах файлов. Если вы хотите использовать формат, подобный Maildir, в такой операционной системе, следует указать другой символ для замены. Восклицательный знак (`'!'`) – популярный выбор. Например:184>185> ```python186> import mailbox187> mailbox.Maildir.colon = '!'188> ```189>190> Атрибут `colon` также может быть установлен для каждого экземпляра отдельно.191192Экземпляры [`Maildir`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Maildir) имеют все методы [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox), а также следующие:193194#### `list_folders()`195196Возвращает список имён всех папок.197198#### `get_folder(folder)`199200Возвращает экземпляр [`Maildir`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Maildir), представляющий папку с именем *folder*. Если папка не существует, возбуждается исключение [`NoSuchMailboxError`](https://python-all.ru/3.9/library/mailbox.html#mailbox.NoSuchMailboxError).201202#### `add_folder(folder)`203204Создаёт папку с именем *folder* и возвращает экземпляр [`Maildir`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Maildir), представляющий её.205206#### `remove_folder(folder)`207208Удаляет папку с именем *folder*. Если папка содержит сообщения, будет возбуждено исключение [`NotEmptyError`](https://python-all.ru/3.9/library/mailbox.html#mailbox.NotEmptyError), и папка не будет удалена.209210#### `clean()`211212Удаляет временные файлы из почтового ящика, к которым не было обращений за последние 36 часов. Спецификация Maildir утверждает, что программы чтения почты должны делать это время от времени.213214Некоторые методы [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox), реализованные в [`Maildir`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Maildir), заслуживают особых замечаний:215216#### `add(message)`217218#### `__setitem__(key, message)`219220#### `update(arg)`221222> **Предупреждение**223>224> Эти методы генерируют уникальные имена файлов на основе идентификатора текущего процесса. При использовании нескольких потоков возможны незамеченные конфликты имен, которые могут привести к повреждению почтового ящика, если потоки не скоординированы, чтобы избежать одновременного использования этих методов для управления одним и тем же почтовым ящиком.225226#### `flush()`227228Все изменения в почтовых ящиках Maildir применяются немедленно, поэтому этот метод ничего не делает.229230#### `lock()`231232#### `unlock()`233234Почтовые ящики Maildir не поддерживают (и не требуют) блокировку, поэтому эти методы ничего не делают.235236#### `close()`237238Экземпляры [`Maildir`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Maildir) не держат открытых файлов, а нижележащие почтовые ящики не поддерживают блокировку, поэтому этот метод ничего не делает.239240#### `get_file(key)`241242В зависимости от платформы может быть невозможно изменить или удалить нижележащее сообщение, пока возвращенный файл остается открытым.243244> **См. также**245>246> **[man-страница maildir из Courier](https://python-all.ru/3.9/library/mailbox.html)**247>248> Спецификация формата. Описывает общее расширение для поддержки папок.249>250> **[Использование формата maildir](https://python-all.ru/3.9/library/mailbox.html)**251>252> Заметки о Maildir от его создателя. Включают обновлённую схему создания имён и детали семантики «info».253254### [`mbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mbox)255256#### `class mailbox.mbox(path, factory=None, create=True)`257258Подкласс [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) для почтовых ящиков в формате mbox. Параметр *factory* – это вызываемый объект, который принимает файлоподобное представление сообщения (ведущее себя как открытое в бинарном режиме) и возвращает пользовательское представление. Если *factory* равен `None`, в качестве представления сообщения по умолчанию используется [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage). Если *create* равен `True`, почтовый ящик создаётся, если он не существует.259260Формат mbox – это классический формат хранения почты в системах Unix. Все сообщения в почтовом ящике mbox хранятся в одном файле, при этом начало каждого сообщения обозначается строкой, первые пять символов которой – «From ».261262Существует несколько вариантов формата mbox, призванных устранить недостатки исходного. В целях совместимости [`mbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mbox) реализует исходный формат, иногда называемый *mboxo*. Это означает, что заголовок *Content-Length*, если он присутствует, игнорируется, а все вхождения «From » в начале строки тела сообщения преобразуются в «\>From » при сохранении сообщения, хотя вхождения «\>From » не преобразуются обратно в «From » при чтении сообщения.263264Некоторые методы [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox), реализованные в [`mbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mbox), заслуживают особых замечаний:265266#### `get_file(key)`267268Использование файла после вызова `flush()` или `close()` для экземпляра [`mbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mbox) может привести к непредсказуемым результатам или вызвать исключение.269270#### `lock()`271272#### `unlock()`273274Используются три механизма блокировки: точечная блокировка (dot locking) и, если доступны, системные вызовы `flock()` и `lockf()`.275276> **См. также**277>278> **[Страница man mbox из tin](https://python-all.ru/3.9/library/mailbox.html)**279>280> Спецификация формата с подробностями о блокировке.281>282> **[Настройка Netscape Mail в Unix: почему формат Content-Length плох](https://python-all.ru/3.9/library/mailbox.html)**283>284> Аргумент в пользу использования оригинального формата mbox, а не его вариации.285>286> **[«mbox» – это семейство нескольких взаимно несовместимых форматов почтовых ящиков](https://python-all.ru/3.9/library/mailbox.html)**287>288> История вариаций mbox.289290### [`MH`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MH)291292#### `class mailbox.MH(path, factory=None, create=True)`293294Подкласс [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) для почтовых ящиков в формате MH. Параметр *factory* – это вызываемый объект, который принимает файлоподобное представление сообщения (ведущее себя как открытое в бинарном режиме) и возвращает пользовательское представление. Если *factory* равен `None`, в качестве представления сообщения по умолчанию используется [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage). Если *create* равен `True`, почтовый ящик создаётся, если он не существует.295296MH – это формат почтовых ящиков на основе каталогов, разработанный для MH Message Handling System, почтового клиента. Каждое сообщение в почтовом ящике MH находится в собственном файле. Почтовый ящик MH может содержать другие почтовые ящики MH (называемые *папками*) помимо сообщений. Папки могут быть вложены неограниченно. Почтовые ящики MH также поддерживают *последовательности* – именованные списки, используемые для логической группировки сообщений без их перемещения в подпапки. Последовательности определяются в файле с именем `.mh_sequences` в каждой папке.297298Класс [`MH`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MH) управляет почтовыми ящиками MH, но не пытается эмулировать все поведения **mh**. В частности, он не изменяет и не зависит от файлов `context` и `.mh_profile`, которые используются программой **mh** для хранения своего состояния и конфигурации.299300Экземпляры [`MH`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MH) имеют все методы [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox), а также следующие:301302#### `list_folders()`303304Возвращает список имён всех папок.305306#### `get_folder(folder)`307308Возвращает экземпляр [`MH`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MH), представляющий папку с именем *folder*. Исключение [`NoSuchMailboxError`](https://python-all.ru/3.9/library/mailbox.html#mailbox.NoSuchMailboxError) возникает, если папка не существует.309310#### `add_folder(folder)`311312Создаёт папку с именем *folder* и возвращает экземпляр [`MH`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MH) представляющий её.313314#### `remove_folder(folder)`315316Удаляет папку с именем *folder*. Если папка содержит сообщения, будет возбуждено исключение [`NotEmptyError`](https://python-all.ru/3.9/library/mailbox.html#mailbox.NotEmptyError), и папка не будет удалена.317318#### `get_sequences()`319320Возвращает словарь, где имена последовательностей сопоставлены со списками ключей. Если последовательностей нет, возвращается пустой словарь.321322#### `set_sequences(sequences)`323324Переопределяет последовательности, существующие в почтовом ящике, на основе *sequences*, словаря, где имена сопоставлены со списками ключей, аналогично возвращаемому [`get_sequences()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MH.get_sequences).325326#### `pack()`327328Переименовывает сообщения в почтовом ящике по мере необходимости для устранения пропусков в нумерации. Записи в списке последовательностей обновляются соответствующим образом.329330> **Примечание**331>332> Ранее выданные ключи становятся недействительными в результате этой операции и не должны использоваться в дальнейшем.333334Некоторые методы [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox), реализованные в [`MH`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MH), заслуживают особых замечаний:335336#### `remove(key)`337338#### `__delitem__(key)`339340#### `discard(key)`341342Эти методы немедленно удаляют сообщение. Соглашение MH помечать сообщение на удаление добавлением запятой к его имени не используется.343344#### `lock()`345346#### `unlock()`347348Используются три механизма блокировки: точечная блокировка и, если доступны, системные вызовы `flock()` и `lockf()`. Для почтовых ящиков MH блокировка почтового ящика означает блокировку файла `.mh_sequences` и, только на время любых операций, затрагивающих их, блокировку отдельных файлов сообщений.349350#### `get_file(key)`351352В зависимости от платформы может быть невозможно удалить базовое сообщение, пока возвращённый файл остаётся открытым.353354#### `flush()`355356Все изменения в почтовых ящиках MH применяются немедленно, поэтому этот метод ничего не делает.357358#### `close()`359360Экземпляры [`MH`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MH) не держат открытых файлов, поэтому этот метод эквивалентен [`unlock()`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MH.unlock).361362> **См. также**363>364> **[nmh – система обработки сообщений](https://python-all.ru/3.9/library/mailbox.html)**365>366> Домашняя страница **nmh**, обновлённой версии исходного **mh**.367>368> **[MH и nmh: электронная почта для пользователей и программистов](https://python-all.ru/3.9/library/mailbox.html)**369>370> Книга, лицензированная под GPL, о **mh** и **nmh**, с некоторой информацией о формате почтового ящика.371372### [`Babyl`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Babyl)373374#### `class mailbox.Babyl(path, factory=None, create=True)`375376Подкласс [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) для почтовых ящиков в формате Babyl. Параметр *factory* – это вызываемый объект, который принимает файлоподобное представление сообщения (ведущее себя как открытое в бинарном режиме) и возвращает пользовательское представление. Если *factory* равно `None`, в качестве представления сообщения по умолчанию используется [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage). Если *create* равно `True`, почтовый ящик создаётся, если он не существует.377378Babyl – это однофайловый формат почтового ящика, используемый почтовым клиентом Rmail, входящим в состав Emacs. Начало сообщения обозначается строкой, содержащей два символа: Control-Подчёркивание (`'\037'`) и Control-L (`'\014'`). Конец сообщения обозначается началом следующего сообщения или, в случае последнего сообщения, строкой, содержащей символ Control-Подчёркивание (`'\037'`).379380Сообщения в почтовом ящике Babyl имеют два набора заголовков: исходные заголовки и так называемые видимые заголовки. Видимые заголовки обычно являются подмножеством исходных заголовков, которые были переформатированы или сокращены для большей привлекательности. Каждое сообщение в почтовом ящике Babyl также имеет сопутствующий список *меток* (коротких строк, которые записывают дополнительную информацию о сообщении), а список всех определённых пользователем меток, найденных в почтовом ящике, хранится в разделе параметров Babyl.381382Экземпляры [`Babyl`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Babyl) имеют все методы [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox), а также следующие:383384#### `get_labels()`385386Возвращает список имён всех определённых пользователем меток, используемых в почтовом ящике.387388> **Примечание**389>390> Фактические сообщения проверяются для определения того, какие метки существуют в почтовом ящике, вместо обращения к списку меток в разделе параметров Babyl, но раздел Babyl обновляется при каждом изменении почтового ящика.391392Некоторые методы [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox), реализованные в [`Babyl`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Babyl), заслуживают особых замечаний:393394#### `get_file(key)`395396В почтовых ящиках Babyl заголовки сообщения не хранятся непрерывно с телом сообщения. Чтобы создать файлоподобное представление, заголовки и тело копируются вместе в экземпляр [`io.BytesIO`](https://python-all.ru/3.9/library/io.html#io.BytesIO), API которого идентичен API файла. В результате файлоподобный объект полностью независим от нижележащего почтового ящика, но не экономит память по сравнению со строковым представлением.397398#### `lock()`399400#### `unlock()`401402Используются три механизма блокировки: точечная блокировка (dot locking) и, если доступны, системные вызовы `flock()` и `lockf()`.403404> **См. также**405>406> **[Формат файлов Babyl версии 5](https://python-all.ru/3.9/library/mailbox.html)**407>408> Спецификация формата Babyl.409>410> **[Чтение почты с помощью Rmail](https://python-all.ru/3.9/library/mailbox.html)**411>412> Руководство по Rmail, содержащее некоторую информацию о семантике Babyl.413414### [`MMDF`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDF)415416#### `class mailbox.MMDF(path, factory=None, create=True)`417418Подкласс [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) для почтовых ящиков в формате MMDF. Параметр *factory* – это вызываемый объект, который принимает файлоподобное представление сообщения (ведущее себя так, как если бы оно было открыто в двоичном режиме) и возвращает пользовательское представление. Если *factory* равно `None`, в качестве представления сообщения по умолчанию используется [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage). Если *create* равно `True`, почтовый ящик создаётся, если он не существует.419420MMDF – это однофайловый формат почтового ящика, разработанный для Multichannel Memorandum Distribution Facility – агента пересылки почты. Каждое сообщение имеет ту же форму, что и сообщение mbox, но обрамляется строками, содержащими четыре символа Control-A (`'\001'`). Как и в формате mbox, начало каждого сообщения обозначается строкой, первые пять символов которой – «From », но дополнительные вхождения «From » не преобразуются в «\>From » при сохранении сообщений, так как дополнительные строки-разделители сообщений предотвращают ошибочный прием таких вхождений за начала последующих сообщений.421422Некоторые методы [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox), реализованные в [`MMDF`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDF), заслуживают особых замечаний:423424#### `get_file(key)`425426Использование файла после вызова `flush()` или `close()` для экземпляра [`MMDF`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDF) может привести к непредсказуемым результатам или вызвать исключение.427428#### `lock()`429430#### `unlock()`431432Используются три механизма блокировки: точечная блокировка (dot locking) и, если доступны, системные вызовы `flock()` и `lockf()`.433434> **См. также**435>436> **[страница руководства mmdf из tin](https://python-all.ru/3.9/library/mailbox.html)**437>438> Спецификация формата MMDF из документации tin, программы для чтения новостей.439>440> **[MMDF](https://python-all.ru/3.9/library/mailbox.html)**441>442> Статья в Википедии, описывающая Multichannel Memorandum Distribution Facility.443444## [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message) объекты445446#### `class mailbox.Message(message=None)`447448Подкласс [`email.message`](https://python-all.ru/3.9/library/email.message.html#module-email.message) модуля [`Message`](https://python-all.ru/3.9/library/email.compat32-message.html#email.message.Message). Подклассы [`mailbox.Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message) добавляют состояние и поведение, специфичные для формата почтового ящика.449450Если *message* опущен, создаётся новый экземпляр в пустом состоянии по умолчанию. Если *message* – экземпляр [`email.message.Message`](https://python-all.ru/3.9/library/email.compat32-message.html#email.message.Message), его содержимое копируется; кроме того, любая форматозависимая информация преобразуется настолько, насколько это возможно, если *message* является экземпляром [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message). Если *message* – строка, байтовая строка или файл, он должен содержать сообщение, совместимое с [**RFC 2822**](https://python-all.ru/3.9/library/mailbox.html), которое читается и разбирается. Файлы должны быть открыты в бинарном режиме, но текстовые файлы принимаются для обратной совместимости.451452Формат-специфичные состояния и поведение, предоставляемые подклассами, различаются, но в целом поддерживаются только те свойства, которые не привязаны к конкретному почтовому ящику (хотя, предположительно, эти свойства специфичны для конкретного формата почтового ящика). Например, смещения в файлах для однофайловых форматов почтовых ящиков и имена файлов для форматов на основе каталогов не сохраняются, так как они применимы только к исходному почтовому ящику. Но такие состояния, как было ли сообщение прочитано пользователем или помечено как важное, сохраняются, поскольку они относятся к самому сообщению.453454Нет требования, чтобы экземпляры [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message) использовались для представления сообщений, полученных с помощью экземпляров [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox). В некоторых ситуациях время и память, необходимые для создания представлений [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message), могут оказаться неприемлемыми. Для таких случаев экземпляры [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) также предлагают строковые и файлоподобные представления, а пользовательская фабрика сообщений может быть указана при инициализации экземпляра [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox).455456### [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage)457458#### `class mailbox.MaildirMessage(message=None)`459460Сообщение с поведением, специфичным для Maildir. Параметр *message* имеет то же значение, что и в конструкторе [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message).461462Обычно почтовый клиент перемещает все сообщения из подкаталога `new` в подкаталог `cur` после того, как пользователь впервые открывает и закрывает почтовый ящик, отмечая, что сообщения старые, независимо от того, были ли они фактически прочитаны. Каждое сообщение в `cur` имеет раздел «info», добавленный к его имени файла для хранения информации о его состоянии. (Некоторые почтовые программы могут также добавлять раздел «info» к сообщениям в `new`.) Раздел «info» может принимать одну из двух форм: он может содержать «2,» с последующим списком стандартизированных флагов (например, «2,FR») или может содержать «1,» с последующей так называемой экспериментальной информацией. Стандартные флаги для сообщений Maildir следующие:463464| Флаг | Значение | Пояснение |465| --- | --- | --- |466| D | Черновик | В процессе составления |467| F | Помечено | Помечено как важное |468| P | Передан | Переслано, отправлено повторно или возвращено |469| R | Отвечено | Получен ответ |470| S | Просмотрено | Прочитано |471| T | Удалено | Помечено для последующего удаления |472473Экземпляры [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage) предоставляют следующие методы:474475#### `get_subdir()`476477Возвращает «new» (если сообщение должно храниться в подкаталоге `new` или «cur» (если сообщение должно храниться в подкаталоге `cur`).478479> **Примечание**480>481> Сообщение обычно перемещается из `new` в `cur` после того, как к его почтовому ящику был получен доступ, независимо от того, было ли сообщение прочитано. Сообщение `msg` считается прочитанным, если `"S" in msg.get_flags()` равно `True`.482483#### `set_subdir(subdir)`484485Устанавливает подкаталог, в котором должно храниться сообщение. Параметр *subdir* должен быть либо «new», либо «cur».486487#### `get_flags()`488489Возвращает строку, указывающую текущие установленные флаги. Если сообщение соответствует стандартному формату Maildir, результатом является конкатенация в алфавитном порядке нуля или одного вхождения каждого из `'D'`, `'F'`, `'P'`, `'R'`, `'S'` и `'T'`. Возвращается пустая строка, если флаги не установлены или если «info» содержит экспериментальную семантику.490491#### `set_flags(flags)`492493Устанавливает флаги, указанные *flags*, и сбрасывает все остальные.494495#### `add_flag(flag)`496497Устанавливает флаг(и), указанные *flag*, не изменяя остальные флаги. Чтобы добавить более одного флага за раз, *flag* может быть строкой из более чем одного символа. Текущий «info» перезаписывается, независимо от того, содержит ли он экспериментальную информацию вместо флагов.498499#### `remove_flag(flag)`500501Сбрасывает флаг(и), указанные в *flag*, не изменяя другие флаги. Чтобы удалить несколько флагов за раз, *flag* может быть строкой из более чем одного символа. Если «info» содержит экспериментальную информацию, а не флаги, текущий «info» не изменяется.502503#### `get_date()`504505Возвращает дату доставки сообщения в виде числа с плавающей запятой, представляющего количество секунд с начала эпохи.506507#### `set_date(date)`508509Устанавливает дату доставки сообщения в *date*, число с плавающей запятой, представляющее количество секунд с начала эпохи.510511#### `get_info()`512513Возвращает строку, содержащую «info» для сообщения. Это полезно для доступа к экспериментальному «info» и его изменения (т.е. не являющегося списком флагов).514515#### `set_info(info)`516517Устанавливает «info» в *info*, которое должно быть строкой.518519Когда экземпляр [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage) создаётся на основе экземпляра [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage) или [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage), заголовки *Status* и *X-Status* опускаются и происходят следующие преобразования:520521| Результирующее состояние | [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage) или [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage) состояние |522| --- | --- |523| Подкаталог «cur» | Флаг O |524| Флаг F | Флаг F |525| Флаг R | Флаг A |526| Флаг S | Флаг R |527| Флаг T | Флаг D |528529Когда экземпляр [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage) создаётся на основе экземпляра [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage), происходят следующие преобразования:530531| Результирующее состояние | Состояние [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage) |532| --- | --- |533| Подкаталог «cur» | последовательность «unseen» |534| подкаталог «cur» и флаг S | нет последовательности «unseen» |535| Флаг F | последовательность «flagged» |536| Флаг R | последовательность «replied» |537538Когда экземпляр [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage) создаётся на основе экземпляра [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage), происходят следующие преобразования:539540| Результирующее состояние | Состояние [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage) |541| --- | --- |542| Подкаталог «cur» | метка «unseen» |543| подкаталог «cur» и флаг S | нет метки «unseen» |544| Флаг P | метка «forwarded» или «resent» |545| Флаг R | метка «отвечено» |546| Флаг T | метка «удалено» |547548### [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage)549550#### `class mailbox.mboxMessage(message=None)`551552Сообщение с поведением, специфичным для mbox. Параметр *message* имеет тот же смысл, что и в конструкторе [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message).553554Сообщения в почтовом ящике mbox хранятся вместе в одном файле. Адрес отправителя (envelope address) и время доставки обычно хранятся в строке, начинающейся с «From », которая используется для обозначения начала сообщения, хотя точный формат этих данных сильно различается в разных реализациях mbox. Флаги, указывающие на состояние сообщения, такие как прочитано или помечено как важное, обычно хранятся в заголовках *Status* и *X-Status*.555556Обычные флаги для сообщений mbox:557558| Флаг | Значение | Пояснение |559| --- | --- | --- |560| R | Прочитано | Прочитано |561| O | Старое | Ранее обнаружено почтовым клиентом |562| D | Удалено | Помечено для последующего удаления |563| F | Помечено | Помечено как важное |564| A | Отвечено | Получен ответ |565566Флаги «R» и «O» хранятся в заголовке *Status*, а флаги «D», «F» и «A» – в заголовке *X-Status*. Флаги и заголовки обычно располагаются в указанном порядке.567568Экземпляры [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage) предоставляют следующие методы:569570#### `get_from()`571572Возвращает строку, представляющую строку «From », отмечающую начало сообщения в почтовом ящике mbox. Начальная «From » и конечный символ новой строки исключаются.573574#### `set_from(from_, time_=None)`575576Устанавливает строку «From » равной *from\_*, которая должна быть указана без начальной «From » или конечного символа новой строки. Для удобства можно указать *time\_*, и она будет правильно отформатирована и добавлена к *from\_*. Если *time\_* указан, это должен быть экземпляр [`time.struct_time`](https://python-all.ru/3.9/library/time.html#time.struct_time), кортеж, подходящий для передачи в [`time.strftime()`](https://python-all.ru/3.9/library/time.html#time.strftime), или `True` (для использования [`time.gmtime()`](https://python-all.ru/3.9/library/time.html#time.gmtime)).577578#### `get_flags()`579580Возвращает строку, указывающую установленные флаги. Если сообщение соответствует стандартному формату, результатом является конкатенация в следующем порядке нуля или одного вхождения каждого из `'R'`, `'O'`, `'D'`, `'F'` и `'A'`.581582#### `set_flags(flags)`583584Устанавливает флаги, указанные в *flags*, и снимает все остальные. Параметр *flags* должен быть конкатенацией в произвольном порядке нуля или более вхождений каждого из `'R'`, `'O'`, `'D'`, `'F'` и `'A'`.585586#### `add_flag(flag)`587588Устанавливает флаг(и), указанные в *flag*, не изменяя другие флаги. Чтобы добавить более одного флага за раз, *flag* может быть строкой из более чем одного символа.589590#### `remove_flag(flag)`591592Снимает флаг(и), указанные в *flag*, не изменяя другие флаги. Чтобы снять несколько флагов одновременно, *flag* может быть строкой из более чем одного символа.593594Когда экземпляр [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage) создается на основе экземпляра [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage), строка «From » генерируется на основе даты доставки экземпляра [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage), и происходят следующие преобразования:595596| Результирующее состояние | Состояние [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage) |597| --- | --- |598| Флаг R | Флаг S |599| Флаг O | Подкаталог «cur» |600| Флаг D | Флаг T |601| Флаг F | Флаг F |602| Флаг A | Флаг R |603604Когда экземпляр [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage) создаётся на основе экземпляра [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage), происходят следующие преобразования:605606| Результирующее состояние | Состояние [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage) |607| --- | --- |608| Флаг R и флаг O | нет последовательности «unseen» |609| Флаг O | последовательность «unseen» |610| Флаг F | последовательность «flagged» |611| Флаг A | последовательность «replied» |612613Когда экземпляр [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage) создаётся на основе экземпляра [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage), происходят следующие преобразования:614615| Результирующее состояние | Состояние [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage) |616| --- | --- |617| Флаг R и флаг O | нет метки «unseen» |618| Флаг O | метка «unseen» |619| Флаг D | метка «удалено» |620| Флаг A | метка «отвечено» |621622Когда экземпляр [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message) создается на основе экземпляра [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage), строка «From » копируется, и все флаги напрямую соответствуют:623624| Результирующее состояние | Состояние [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage) |625| --- | --- |626| Флаг R | Флаг R |627| Флаг O | Флаг O |628| Флаг D | Флаг D |629| Флаг F | Флаг F |630| Флаг A | Флаг A |631632### [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage)633634#### `class mailbox.MHMessage(message=None)`635636Сообщение с поведением, характерным для MH. Параметр *message* имеет то же значение, что и в конструкторе [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message).637638Сообщения MH не поддерживают метки и флаги в традиционном понимании, но поддерживают последовательности – логические группировки произвольных сообщений. Некоторые почтовые программы (хотя не стандартные **mh** и **nmh**) используют последовательности примерно так же, как флаги используются в других форматах:639640| Последовательность | Пояснение |641| --- | --- |642| непрочитанное | Не прочитано, но ранее обнаружено почтовым клиентом (MUA) |643| отвечено | Получен ответ |644| помечено | Помечено как важное |645646Экземпляры [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage) предоставляют следующие методы:647648#### `get_sequences()`649650Возвращает список имен последовательностей, которые включают это сообщение.651652#### `set_sequences(sequences)`653654Устанавливает список последовательностей, которые включают это сообщение.655656#### `add_sequence(sequence)`657658Добавляет *sequence* в список последовательностей, которые включают это сообщение.659660#### `remove_sequence(sequence)`661662Удаляет *sequence* из списка последовательностей, которые включают это сообщение.663664Когда экземпляр [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage) создаётся на основе экземпляра [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage), происходят следующие преобразования:665666| Результирующее состояние | Состояние [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage) |667| --- | --- |668| последовательность «unseen» | нет флага S |669| последовательность «replied» | Флаг R |670| последовательность «flagged» | Флаг F |671672Когда экземпляр [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage) создается на основе экземпляра [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage) или [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage), заголовки *Status* и *X-Status* опускаются и происходят следующие преобразования:673674| Результирующее состояние | [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage) или [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage) состояние |675| --- | --- |676| последовательность «unseen» | нет флага R |677| последовательность «replied» | Флаг A |678| последовательность «flagged» | Флаг F |679680Когда экземпляр [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage) создаётся на основе экземпляра [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage), происходят следующие преобразования:681682| Результирующее состояние | Состояние [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage) |683| --- | --- |684| последовательность «unseen» | метка «unseen» |685| последовательность «replied» | метка «отвечено» |686687### [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage)688689#### `class mailbox.BabylMessage(message=None)`690691Сообщение с поведением, специфичным для Babyl. Параметр *message* имеет то же значение, что и в конструкторе [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message).692693Некоторые метки сообщений, называемые *attributes*, по соглашению имеют специальное значение. Атрибуты следующие:694695| Метка | Пояснение |696| --- | --- |697| непрочитанное | Не прочитано, но ранее обнаружено почтовым клиентом (MUA) |698| удалено | Помечено для последующего удаления |699| архивировано | Скопировано в другой файл или почтовый ящик |700| отвечено | Получен ответ |701| переслано | Переслано |702| изменено | Изменено пользователем |703| переотправлено | Отправлено повторно |704705По умолчанию Rmail отображает только видимые заголовки. Однако класс [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage) использует исходные заголовки, поскольку они более полны. При желании к видимым заголовкам можно обратиться явно.706707Экземпляры [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage) предоставляют следующие методы:708709#### `get_labels()`710711Возвращает список меток сообщения.712713#### `set_labels(labels)`714715Устанавливает список меток сообщения равным *labels*.716717#### `add_label(label)`718719Добавляет метку *label* в список меток сообщения.720721#### `remove_label(label)`722723Удаляет метку *label* из списка меток сообщения.724725#### `get_visible()`726727Возвращает экземпляр [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message), содержащий видимые заголовки сообщения и пустое тело.728729#### `set_visible(visible)`730731Устанавливает видимые заголовки сообщения такими же, как заголовки из *message*. Параметр *visible* должен быть экземпляром [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message), экземпляром [`email.message.Message`](https://python-all.ru/3.9/library/email.compat32-message.html#email.message.Message), строкой или файлоподобным объектом (который должен быть открыт в текстовом режиме).732733#### `update_visible()`734735Когда исходные заголовки экземпляра [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage) изменяются, видимые заголовки автоматически не изменяются для соответствия. Этот метод обновляет видимые заголовки следующим образом: каждый видимый заголовок с соответствующим исходным заголовком устанавливается в значение исходного заголовка, каждый видимый заголовок без соответствующего исходного заголовка удаляется, а любые из *Date*, *From*, *Reply-To*, *To*, *CC* и *Subject*, которые присутствуют в исходных заголовках, но отсутствуют в видимых заголовках, добавляются к видимым заголовкам.736737Когда экземпляр [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage) создаётся на основе экземпляра [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage), происходят следующие преобразования:738739| Результирующее состояние | Состояние [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage) |740| --- | --- |741| метка «unseen» | нет флага S |742| метка «удалено» | Флаг T |743| метка «отвечено» | Флаг R |744| Метка «forwarded» | Флаг P |745746Когда экземпляр [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage) создаётся на основе экземпляра [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage) или [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage), заголовки *Status* и *X-Status* опускаются и происходят следующие преобразования:747748| Результирующее состояние | [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage) или [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage) состояние |749| --- | --- |750| метка «unseen» | нет флага R |751| метка «удалено» | Флаг D |752| метка «отвечено» | Флаг A |753754Когда экземпляр [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage) создаётся на основе экземпляра [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage), происходят следующие преобразования:755756| Результирующее состояние | Состояние [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage) |757| --- | --- |758| метка «unseen» | последовательность «unseen» |759| метка «отвечено» | последовательность «replied» |760761### [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage)762763#### `class mailbox.MMDFMessage(message=None)`764765Сообщение с поведением, специфичным для MMDF. Параметр *message* имеет то же значение, что и в конструкторе [`Message`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Message).766767Как и сообщения в почтовом ящике mbox, сообщения MMDF хранятся с адресом отправителя и датой доставки в начальной строке, начинающейся с «From ». Аналогично, флаги, указывающие на состояние сообщения, обычно хранятся в заголовках *Status* и *X-Status*.768769Стандартные флаги для сообщений MMDF совпадают с флагами сообщений mbox и перечислены ниже:770771| Флаг | Значение | Пояснение |772| --- | --- | --- |773| R | Прочитано | Прочитано |774| O | Старое | Ранее обнаружено почтовым клиентом |775| D | Удалено | Помечено для последующего удаления |776| F | Помечено | Помечено как важное |777| A | Отвечено | Получен ответ |778779Флаги «R» и «O» хранятся в заголовке *Status*, а флаги «D», «F» и «A» – в заголовке *X-Status*. Флаги и заголовки обычно располагаются в указанном порядке.780781Экземпляры [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage) предоставляют следующие методы, идентичные методам, предоставляемым [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage):782783#### `get_from()`784785Возвращает строку, представляющую строку «From », отмечающую начало сообщения в почтовом ящике mbox. Начальная «From » и конечный символ новой строки исключаются.786787#### `set_from(from_, time_=None)`788789Устанавливает строку «From » равной *from\_*, которая должна быть указана без начальной «From » или конечного символа новой строки. Для удобства можно указать *time\_*, и она будет правильно отформатирована и добавлена к *from\_*. Если *time\_* указан, это должен быть экземпляр [`time.struct_time`](https://python-all.ru/3.9/library/time.html#time.struct_time), кортеж, подходящий для передачи в [`time.strftime()`](https://python-all.ru/3.9/library/time.html#time.strftime), или `True` (для использования [`time.gmtime()`](https://python-all.ru/3.9/library/time.html#time.gmtime)).790791#### `get_flags()`792793Возвращает строку, указывающую установленные флаги. Если сообщение соответствует стандартному формату, результатом является конкатенация в следующем порядке нуля или одного вхождения каждого из `'R'`, `'O'`, `'D'`, `'F'` и `'A'`.794795#### `set_flags(flags)`796797Устанавливает флаги, указанные в *flags*, и снимает все остальные. Параметр *flags* должен быть конкатенацией в произвольном порядке нуля или более вхождений каждого из `'R'`, `'O'`, `'D'`, `'F'` и `'A'`.798799#### `add_flag(flag)`800801Устанавливает флаг(и), указанные в *flag*, не изменяя другие флаги. Чтобы добавить более одного флага за раз, *flag* может быть строкой из более чем одного символа.802803#### `remove_flag(flag)`804805Снимает флаг(и), указанные в *flag*, не изменяя другие флаги. Чтобы снять несколько флагов одновременно, *flag* может быть строкой из более чем одного символа.806807Когда экземпляр [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage) создается на основе экземпляра [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage), строка «From » генерируется на основе даты доставки экземпляра [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage), и происходят следующие преобразования:808809| Результирующее состояние | Состояние [`MaildirMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MaildirMessage) |810| --- | --- |811| Флаг R | Флаг S |812| Флаг O | Подкаталог «cur» |813| Флаг D | Флаг T |814| Флаг F | Флаг F |815| Флаг A | Флаг R |816817Когда экземпляр [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage) создаётся на основе экземпляра [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage), происходят следующие преобразования:818819| Результирующее состояние | Состояние [`MHMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MHMessage) |820| --- | --- |821| Флаг R и флаг O | нет последовательности «unseen» |822| Флаг O | последовательность «unseen» |823| Флаг F | последовательность «flagged» |824| Флаг A | последовательность «replied» |825826Когда экземпляр [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage) создаётся на основе экземпляра [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage), происходят следующие преобразования:827828| Результирующее состояние | Состояние [`BabylMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.BabylMessage) |829| --- | --- |830| Флаг R и флаг O | нет метки «unseen» |831| Флаг O | метка «unseen» |832| Флаг D | метка «удалено» |833| Флаг A | метка «отвечено» |834835Когда экземпляр [`MMDFMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MMDFMessage) создается на основе экземпляра [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage), строка «From » копируется, и все флаги напрямую соответствуют:836837| Результирующее состояние | Состояние [`mboxMessage`](https://python-all.ru/3.9/library/mailbox.html#mailbox.mboxMessage) |838| --- | --- |839| Флаг R | Флаг R |840| Флаг O | Флаг O |841| Флаг D | Флаг D |842| Флаг F | Флаг F |843| Флаг A | Флаг A |844845## Исключения846847В модуле [`mailbox`](https://python-all.ru/3.9/library/mailbox.html#module-mailbox) определены следующие классы исключений:848849#### `exception mailbox.Error`850851Базовый класс для всех остальных исключений, специфичных для модуля.852853#### `exception mailbox.NoSuchMailboxError`854855Вызывается, когда ожидается почтовый ящик, но он не найден, например, при создании экземпляра подкласса [`Mailbox`](https://python-all.ru/3.9/library/mailbox.html#mailbox.Mailbox) с несуществующим путём (и с параметром *create*, установленным в `False`) или при открытии несуществующей папки.856857#### `exception mailbox.NotEmptyError`858859Вызывается, когда почтовый ящик не пуст, но ожидается пустым, например, при удалении папки, содержащей сообщения.860861#### `exception mailbox.ExternalClashError`862863Возникает, когда не зависящее от программы условие, связанное с почтовым ящиком, не позволяет продолжить работу, например, когда не удаётся получить блокировку, которая уже удерживается другой программой, или когда сгенерированное уникальное имя файла уже существует.864865#### `exception mailbox.FormatError`866867Вызывается, когда данные в файле не могут быть разобраны, например, когда экземпляр [`MH`](https://python-all.ru/3.9/library/mailbox.html#mailbox.MH) пытается прочитать повреждённый файл `.mh_sequences`.868869## Примеры870871Простой пример вывода тем всех сообщений в почтовом ящике, которые кажутся интересными:872873```python874import mailbox875for message in mailbox.mbox('~/mbox'):876 subject = message['subject'] # Может быть None.877 if subject and 'python' in subject.lower():878 print(subject)879```880881Чтобы скопировать все письма из почтового ящика Babyl в почтовый ящик MH, преобразуя всю форматно-специфичную информацию, которую можно преобразовать:882883```python884import mailbox885destination = mailbox.MH('~/Mail')886destination.lock()887for message in mailbox.Babyl('~/RMAIL'):888 destination.add(mailbox.MHMessage(message))889destination.flush()890destination.unlock()891```892893Этот пример сортирует письма из нескольких списков рассылки по разным почтовым ящикам, стараясь избежать повреждения писем из-за одновременного изменения другими программами, потери писем из-за прерывания программы или преждевременного завершения из-за повреждённых сообщений в почтовом ящике:894895```python896import mailbox897import email.errors898899list_names = ('python-list', 'python-dev', 'python-bugs')900901boxes = {name: mailbox.mbox('~/email/%s' % name) for name in list_names}902inbox = mailbox.Maildir('~/Maildir', factory=None)903904for key in inbox.iterkeys():905 try:906 message = inbox[key]907 except email.errors.MessageParseError:908 continue # Сообщение повреждено. Просто оставьте его.909910 for name in list_names:911 list_id = message['list-id']912 if list_id and name in list_id:913 # Получить почтовый ящик для использования.914 box = boxes[name]915916 # Записать копию на диск перед удалением оригинала.917 # Если произошёл сбой, возможно дублирование сообщения, но918 # это лучше, чем полная потеря сообщения.919 box.lock()920 box.add(message)921 box.flush()922 box.unlock()923924 # Удалить исходное сообщение925 inbox.lock()926 inbox.discard(key)927 inbox.flush()928 inbox.unlock()929 break # Целевой получатель найден, поиск прекращён.930931for box in boxes.itervalues():932 box.close()933```934