mailbox — 以各種格式操作郵箱

原始碼: Lib/mailbox.py


此模組定義了兩個類,MailboxMessage,用於訪問和操作磁碟上的郵箱及其包含的訊息。Mailbox 提供了一個從鍵到訊息的字典式對映。Message 擴充套件了 email.message 模組的 Message 類,並帶有格式特定的狀態和行為。支援的郵箱格式有 Maildir、mbox、MH、Babyl 和 MMDF。

參見

模組 email

表示和操作訊息。

Mailbox 物件

class mailbox.Mailbox

一個郵箱,可以被檢查和修改。

Mailbox 類定義了一個介面,不應直接例項化。相反,格式特定的子類應該繼承自 Mailbox,您的程式碼應該例項化一個特定的子類。

Mailbox 介面類似於字典,小鍵對應於訊息。鍵由與其一起使用的 Mailbox 例項發出,並且僅對該 Mailbox 例項有意義。即使相應的訊息被修改,例如透過替換為另一條訊息,鍵也繼續標識該訊息。

訊息可以使用類似集合的方法 add() 新增到 Mailbox 例項,並使用 del 語句或類似集合的方法 remove()discard() 刪除。

Mailbox 介面的語義與字典語義在某些值得注意的方面有所不同。每次請求訊息時,都會根據郵箱的當前狀態生成一個新的表示(通常是 Message 例項)。類似地,當訊息新增到 Mailbox 例項時,所提供的訊息表示的內容會被複制。在這兩種情況下,Mailbox 例項都不會保留對訊息表示的引用。

預設的 Mailbox 迭代器 迭代訊息表示,而不是像預設 字典 迭代器那樣迭代鍵。此外,在迭代期間修改郵箱是安全且定義明確的。迭代器建立後新增到郵箱的訊息將不會被迭代器看到。在迭代器產生訊息之前從郵箱中刪除的訊息將被靜默跳過,但如果相應的訊息隨後被刪除,使用迭代器中的鍵可能會導致 KeyError 異常。

警告

當修改可能被其他程序同時更改的郵箱時要非常小心。用於此類任務的最安全的郵箱格式是 Maildir;儘量避免使用單檔案格式,例如 mbox 進行併發寫入。如果您正在修改郵箱,則必須在讀取檔案中的任何訊息或透過新增或刪除訊息進行任何更改之前,透過呼叫 lock()unlock() 方法來鎖定它。未能鎖定郵箱可能會導致訊息丟失或整個郵箱損壞的風險。

Mailbox 例項具有以下方法

add(message)

message 新增到郵箱並返回已分配給它的鍵。

引數 message 可以是 Message 例項、email.message.Message 例項、字串、位元組字串或類檔案物件(應以二進位制模式開啟)。如果 message 是適當的格式特定 Message 子類例項(例如,如果它是 mboxMessage 例項且這是 mbox 例項),則使用其格式特定資訊。否則,使用格式特定資訊的合理預設值。

3.2 版中已更改: 添加了對二進位制輸入的支援。

remove(key)
__delitem__(key)
discard(key)

從郵箱中刪除與 key 對應的訊息。

如果不存在這樣的訊息,如果方法被呼叫為 remove()__delitem__(),則會引發 KeyError 異常,但如果方法被呼叫為 discard(),則不會引發異常。discard() 的行為可能更受歡迎,如果底層郵箱格式支援其他程序併發修改。

__setitem__(key, message)

message 替換與 key 對應的訊息。如果郵箱中沒有訊息與 key 對應,則引發 KeyError 異常。

add() 類似,引數 message 可以是 Message 例項、email.message.Message 例項、字串、位元組字串或類檔案物件(應以二進位制模式開啟)。如果 message 是適當的格式特定 Message 子類例項(例如,如果它是 mboxMessage 例項且這是 mbox 例項),則使用其格式特定資訊。否則,當前與 key 對應的訊息的格式特定資訊將保持不變。

iterkeys()

返回所有鍵的 迭代器

keys()

iterkeys() 相同,只是返回的是 list 而不是 迭代器

itervalues()
__iter__()

返回所有訊息表示的 迭代器。除非在初始化 Mailbox 例項時指定了自定義訊息工廠,否則訊息將表示為適當的格式特定 Message 子類的例項。

備註

__iter__() 的行為與字典不同,字典迭代的是鍵。

values()

itervalues() 相同,只是返回的是 list 而不是 迭代器

iteritems()

返回 (key, message) 對的 迭代器,其中 key 是一個鍵,message 是一個訊息表示。除非在初始化 Mailbox 例項時指定了自定義訊息工廠,否則訊息將表示為適當的格式特定 Message 子類的例項。

items()

iteritems() 相同,只是返回的是對的 list 而不是對的 迭代器

get(key, default=None)
__getitem__(key)

返回與 key 對應的訊息的表示。如果不存在這樣的訊息,如果方法被呼叫為 get(),則返回 default,如果方法被呼叫為 __getitem__(),則引發 KeyError 異常。除非在初始化 Mailbox 例項時指定了自定義訊息工廠,否則訊息將表示為適當的格式特定 Message 子類的例項。

get_message(key)

返回與 key 對應的訊息的表示,作為適當的格式特定 Message 子類的例項,如果不存在此類訊息,則引發 KeyError 異常。

get_bytes(key)

返回與 key 對應的訊息的位元組表示,如果不存在此類訊息,則引發 KeyError 異常。

在 3.2 版本加入。

get_string(key)

返回與 key 對應的訊息的字串表示,如果不存在此類訊息,則引發 KeyError 異常。訊息透過 email.message.Message 處理以將其轉換為 7 位純淨表示。

get_file(key)

返回與 key 對應的訊息的 類檔案 表示,如果不存在此類訊息,則引發 KeyError 異常。類檔案物件的行為就像以二進位制模式開啟一樣。此檔案在不再需要時應關閉。

3.2 版中已更改: 檔案物件確實是 二進位制檔案;以前它以文字模式錯誤地返回。此外,類檔案物件 現在支援 上下文管理器 協議:您可以使用 with 語句自動關閉它。

備註

與其他訊息表示不同,類檔案 表示不一定獨立於建立它們的 Mailbox 例項或底層郵箱。更具體的文件由每個子類提供。

__contains__(key)

如果 key 對應於一條訊息,則返回 True,否則返回 False

__len__()

返回郵箱中訊息的數量。

clear()

刪除郵箱中的所有訊息。

pop(key, default=None)

返回與 key 對應的訊息的表示並刪除該訊息。如果不存在此類訊息,則返回 default。除非在初始化 Mailbox 例項時指定了自定義訊息工廠,否則訊息將表示為適當的格式特定 Message 子類的例項。

popitem()

返回任意 (key, message) 對,其中 key 是一個鍵,message 是一個訊息表示,並刪除相應的訊息。如果郵箱為空,則引發 KeyError 異常。除非在初始化 Mailbox 例項時指定了自定義訊息工廠,否則訊息將表示為適當的格式特定 Message 子類的例項。

update(arg)

引數 arg 應該是一個 key-到-message 對映或一個 (key, message) 對的可迭代物件。更新郵箱,以便對於每個給定的 keymessage,將與 key 對應的訊息設定為 message,就像使用 __setitem__() 一樣。與 __setitem__() 類似,每個 key 必須已經對應於郵箱中的一條訊息,否則將引發 KeyError 異常,因此通常 arg 不應是 Mailbox 例項。

備註

與字典不同,不支援關鍵字引數。

flush()

將所有待處理的更改寫入檔案系統。對於某些 Mailbox 子類,更改總是立即寫入,flush() 不執行任何操作,但您仍應養成呼叫此方法的習慣。

lock()

在郵箱上獲取獨佔性建議鎖,以便其他程序知道不要修改它。如果鎖不可用,則引發 ExternalClashError。使用的特定鎖定機制取決於郵箱格式。在對郵箱內容進行任何修改之前,您總是應該鎖定郵箱。

unlock()

釋放郵箱上的鎖(如果有)。

close()

清空郵箱,如有必要則解鎖,並關閉所有開啟的檔案。對於某些 Mailbox 子類,此方法不執行任何操作。

Maildir 物件

class mailbox.Maildir(dirname, factory=None, create=True)

Mailbox 的子類,用於 Maildir 格式的郵箱。引數 factory 是一個可呼叫物件,它接受一個類檔案訊息表示(其行為就像以二進位制模式開啟一樣)並返回一個自定義表示。如果 factoryNone,則 MaildirMessage 用作預設訊息表示。如果 createTrue,則如果郵箱不存在,則建立郵箱。

如果 createTruedirname 路徑存在,則它將被視為現有 maildir,而無需嘗試驗證其目錄佈局。

出於歷史原因,dirname 被命名為 dirname 而不是 path

Maildir 是一種基於目錄的郵箱格式,是為 qmail 郵件傳輸代理發明的,現在被其他程式廣泛支援。Maildir 郵箱中的訊息以單獨的檔案儲存在公共目錄結構中。這種設計允許 Maildir 郵箱被多個不相關的程式訪問和修改而不會損壞資料,因此不需要檔案鎖定。

Maildir 郵箱包含三個子目錄,即:tmpnewcur。訊息在 tmp 子目錄中暫時建立,然後移動到 new 子目錄以最終完成遞送。郵件使用者代理隨後可以將訊息移動到 cur 子目錄,並將其狀態資訊儲存在附加到其檔名的特殊“info”部分中。

還支援 Courier 郵件傳輸代理引入的資料夾樣式。主郵箱的任何子目錄如果其名稱的第一個字元是 '.',則被視為資料夾。Maildir 表示的資料夾名稱不帶前導 '.'。每個資料夾本身都是一個 Maildir 郵箱,但不應包含其他資料夾。相反,使用 '.' 來分隔級別以指示邏輯巢狀,例如,“Archived.2005.07”。

colon

Maildir 規範要求在某些訊息檔名中使用冒號(':')。但是,某些作業系統不允許在檔名中使用此字元。如果您希望在此類作業系統上使用 Maildir 格式,則應指定要使用的其他字元。感嘆號('!')是一個流行的選擇。例如

import mailbox
mailbox.Maildir.colon = '!'

colon 屬性也可以按例項設定。

3.13 版中已更改: Maildir 現在忽略帶有前導點的檔案。

Maildir 例項除了具有 Mailbox 的所有方法外,還具有以下方法

list_folders()

返回所有資料夾名稱的列表。

get_folder(folder)

返回一個 Maildir 例項,表示名稱為 folder 的資料夾。如果資料夾不存在,則引發 NoSuchMailboxError 異常。

add_folder(folder)

建立一個名稱為 folder 的資料夾,並返回表示它的 Maildir 例項。

remove_folder(folder)

刪除名稱為 folder 的資料夾。如果資料夾包含任何訊息,則將引發 NotEmptyError 異常,並且資料夾將不會被刪除。

clean()

刪除郵箱中過去 36 小時內未訪問過的臨時檔案。Maildir 規範規定郵件讀取程式應偶爾執行此操作。

get_flags(key)

以字串形式返回與 key 對應的訊息上設定的標誌。這與 get_message(key).get_flags() 相同,但速度快得多,因為它不開啟訊息檔案。在迭代鍵以確定哪些訊息值得獲取時使用此方法。

如果您確實有一個 MaildirMessage 物件,請改用其 get_flags() 方法,因為在呼叫郵箱的 __setitem__() 方法之前,訊息的 set_flags()add_flag()remove_flag() 方法所做的更改不會反映在此處。

在 3.13 版本加入。

set_flags(key, flags)

在與 key 對應的訊息上,設定 flags 指定的標誌並取消設定所有其他標誌。呼叫 some_mailbox.set_flags(key, flags) 類似於

one_message = some_mailbox.get_message(key)
one_message.set_flags(flags)
some_mailbox[key] = one_message

但速度更快,因為它不開啟訊息檔案。

如果您確實有一個 MaildirMessage 物件,請改用其 set_flags() 方法,因為使用此郵箱方法所做的更改不會對訊息物件的 get_flags() 方法可見。

在 3.13 版本加入。

add_flag(key, flag)

在與 key 對應的訊息上,設定 flag 指定的標誌而不更改其他標誌。要一次新增多個標誌,flag 可以是包含多個字元的字串。

使用此方法與訊息物件的 add_flag() 方法的考慮因素與 set_flags() 類似;請參見那裡的討論。

在 3.13 版本加入。

remove_flag(key, flag)

在與 key 對應的訊息上,取消設定 flag 指定的標誌而不更改其他標誌。要一次刪除多個標誌,flag 可以是包含多個字元的字串。

使用此方法與訊息物件的 remove_flag() 方法的考慮因素與 set_flags() 類似;請參見那裡的討論。

在 3.13 版本加入。

get_info(key)

返回一個字串,其中包含與 key 對應的訊息的資訊。這與 get_message(key).get_info() 相同,但速度快得多,因為它不開啟訊息檔案。在迭代鍵以確定哪些訊息值得獲取時使用此方法。

如果您確實有一個 MaildirMessage 物件,請改用其 get_info() 方法,因為在呼叫郵箱的 __setitem__() 方法之前,訊息的 set_info() 方法所做的更改不會反映在此處。

在 3.13 版本加入。

set_info(key, info)

將與 key 對應的訊息的資訊設定為 info。呼叫 some_mailbox.set_info(key, flags) 類似於

one_message = some_mailbox.get_message(key)
one_message.set_info(info)
some_mailbox[key] = one_message

但速度更快,因為它不開啟訊息檔案。

如果您確實有一個 MaildirMessage 物件,請改用其 set_info() 方法,因為使用此郵箱方法所做的更改不會對訊息物件的 get_info() 方法可見。

在 3.13 版本加入。

Maildir 實現的一些 Mailbox 方法值得特別說明

add(message)
__setitem__(key, message)
update(arg)

警告

這些方法根據當前程序 ID 生成唯一的檔名。在使用多個執行緒時,可能會發生未檢測到的名稱衝突,並導致郵箱損壞,除非執行緒協同避免同時使用這些方法操作同一個郵箱。

flush()

對 Maildir 郵箱的所有更改都會立即應用,因此此方法不執行任何操作。

lock()
unlock()

Maildir 郵箱不支援(或不需要)鎖定,因此這些方法不執行任何操作。

close()

Maildir 例項不保留任何開啟的檔案,底層郵箱不支援鎖定,因此此方法不執行任何操作。

get_file(key)

根據主機平臺的不同,在返回的檔案保持開啟狀態時,可能無法修改或刪除底層訊息。

參見

來自 Courier 的 maildir 手冊頁

一種格式規範。描述了支援資料夾的常見擴充套件。

使用maildir格式

其發明者關於 Maildir 的注意事項。包括更新的名稱建立方案和“資訊”語義的詳細資訊。

mbox 物件

class mailbox.mbox(path, factory=None, create=True)

Mailbox 的子類,用於 mbox 格式的郵箱。引數 factory 是一個可呼叫物件,它接受一個類檔案訊息表示(其行為就像以二進位制模式開啟一樣)並返回一個自定義表示。如果 factoryNone,則 mboxMessage 用作預設訊息表示。如果 createTrue,則如果郵箱不存在,則建立郵箱。

mbox 格式是 Unix 系統上儲存郵件的經典格式。mbox 郵箱中的所有訊息都儲存在一個檔案中,每條訊息的開頭由一行指示,該行的前五個字元是“From ”。

mbox 格式存在幾種變體,以解決原始格式中感知到的缺點。為了相容性,mbox 實現了原始格式,有時也稱為 mboxo。這意味著如果存在 Content-Length 標頭,它將被忽略,並且訊息正文中行開頭的任何“From ”出現都會在儲存訊息時轉換為“>From ”,儘管在讀取訊息時“>From ”的出現不會轉換為“From ”。

mbox 實現的一些 Mailbox 方法值得特別說明

get_bytes(key, from_=False)

注意:與其他類相比,此方法有一個額外的引數(from_)。mbox 檔案條目的第一行是 Unix 的“From ”行。如果 from_ 為 False,則檔案中的第一行將被丟棄。

get_file(key, from_=False)

mbox 例項上呼叫 flush()close() 後使用檔案可能會產生不可預測的結果或引發異常。

注意:與其他類相比,此方法有一個額外的引數(from_)。mbox 檔案條目的第一行是 Unix 的“From ”行。如果 from_ 為 False,則檔案中的第一行將被丟棄。

get_string(key, from_=False)

注意:與其他類相比,此方法有一個額外的引數(from_)。mbox 檔案條目的第一行是 Unix 的“From ”行。如果 from_ 為 False,則檔案中的第一行將被丟棄。

lock()
unlock()

使用了三種鎖定機制——點鎖定,以及如果可用,flock()lockf() 系統呼叫。

參見

來自 tin 的 mbox 手冊頁

格式規範,包含鎖定細節。

在 Unix 上配置 Netscape Mail:為什麼 Content-Length 格式很糟糕

主張使用原始 mbox 格式而不是變體。

“mbox”是幾種互不相容的郵箱格式族

mbox 變體歷史。

MH 物件

class mailbox.MH(path, factory=None, create=True)

Mailbox 的子類,用於 MH 格式的郵箱。引數 factory 是一個可呼叫物件,它接受一個類檔案訊息表示(其行為就像以二進位制模式開啟一樣)並返回一個自定義表示。如果 factoryNone,則 MHMessage 用作預設訊息表示。如果 createTrue,則如果郵箱不存在,則建立郵箱。

MH 是一種基於目錄的郵箱格式,是為 MH Message Handling System(一種郵件使用者代理)發明的。MH 郵箱中的每條訊息都位於自己的檔案中。MH 郵箱除了訊息外,還可以包含其他 MH 郵箱(稱為 資料夾)。資料夾可以無限巢狀。MH 郵箱還支援 序列,它們是用於邏輯分組訊息而不將其移動到子資料夾的命名列表。序列在每個資料夾中名為 .mh_sequences 的檔案中定義。

MH 類操作 MH 郵箱,但它不試圖模擬 mh 的所有行為。特別是,它不修改也不受 mh 用於儲存其狀態和配置的 context.mh_profile 檔案影響。

MH 例項除了具有 Mailbox 的所有方法外,還具有以下方法

3.13 版中已更改: 支援不包含 .mh_sequences 檔案的資料夾。

list_folders()

返回所有資料夾名稱的列表。

get_folder(folder)

返回一個 MH 例項,表示名稱為 folder 的資料夾。如果資料夾不存在,則引發 NoSuchMailboxError 異常。

add_folder(folder)

建立一個名稱為 folder 的資料夾,並返回表示它的 MH 例項。

remove_folder(folder)

刪除名稱為 folder 的資料夾。如果資料夾包含任何訊息,則將引發 NotEmptyError 異常,並且資料夾將不會被刪除。

get_sequences()

返回一個序列名稱對映到鍵列表的字典。如果沒有序列,則返回空字典。

set_sequences(sequences)

根據 sequences(一個名稱對映到鍵列表的字典,如 get_sequences() 返回的那樣)重新定義郵箱中存在的序列。

pack()

根據需要重新命名郵箱中的訊息以消除編號中的空白。序列列表中的條目也會相應更新。

備註

此操作會使已發出的鍵失效,之後不應再使用。

MH 實現的一些 Mailbox 方法值得特別說明

remove(key)
__delitem__(key)
discard(key)

這些方法立即刪除訊息。不使用 MH 慣例,即透過在訊息名稱前新增逗號來標記要刪除的訊息。

lock()
unlock()

使用了三種鎖定機制——點鎖定,以及如果可用,flock()lockf() 系統呼叫。對於 MH 郵箱,鎖定郵箱意味著鎖定 .mh_sequences 檔案,並且僅在影響它們的任何操作期間鎖定單個訊息檔案。

get_file(key)

根據主機平臺的不同,在返回的檔案保持開啟狀態時,可能無法刪除底層訊息。

flush()

對 MH 郵箱的所有更改都會立即應用,因此此方法不執行任何操作。

close()

MH 例項不保留任何開啟的檔案,因此此方法等同於 unlock()

參見

nmh - 訊息處理系統

nmh 的主頁,它是原始 mh 的更新版本。

MH & nmh: 適用於使用者和程式設計師的電子郵件

一本關於 mhnmh 的 GPL 許可書籍,其中包含一些關於郵箱格式的資訊。

Babyl 物件

class mailbox.Babyl(path, factory=None, create=True)

Mailbox 的子類,用於 Babyl 格式的郵箱。引數 factory 是一個可呼叫物件,它接受一個類檔案訊息表示(其行為就像以二進位制模式開啟一樣)並返回一個自定義表示。如果 factoryNone,則 BabylMessage 用作預設訊息表示。如果 createTrue,則如果郵箱不存在,則建立郵箱。

Babyl 是 Emacs 附帶的 Rmail 郵件使用者代理使用的一種單檔案郵箱格式。訊息的開頭由一行包含兩個字元 Control-Underscore ('\037') 和 Control-L ('\014') 的行表示。訊息的結尾由下一條訊息的開始或(在最後一條訊息的情況下)包含 Control-Underscore ('\037') 字元的行表示。

Babyl 郵箱中的訊息有兩組標頭:原始標頭和所謂的可見標頭。可見標頭通常是原始標頭的一個子集,經過重新格式化或刪節以使其更具吸引力。Babyl 郵箱中的每條訊息還附帶一個 標籤 列表,即記錄有關訊息的額外資訊的短字串,並且郵箱中找到的所有使用者定義標籤的列表都儲存在 Babyl 選項部分中。

Babyl 例項除了具有 Mailbox 的所有方法外,還具有以下方法

get_labels()

返回郵箱中使用的所有使用者定義標籤名稱的列表。

備註

檢查實際訊息以確定郵箱中存在哪些標籤,而不是查閱 Babyl 選項部分中的標籤列表,但每當修改郵箱時,Babyl 部分都會更新。

Babyl 實現的一些 Mailbox 方法值得特別說明

get_file(key)

在Babyl郵箱中,郵件的標題不與郵件正文連續儲存。為了生成檔案式的表示,標題和正文被複制到一個 io.BytesIO 例項中,該例項具有與檔案相同的API。因此,這個檔案式物件獨立於底層郵箱,但與字串表示相比,它不節省記憶體。

lock()
unlock()

使用了三種鎖定機制——點鎖定,以及如果可用,flock()lockf() 系統呼叫。

參見

版本5 Babyl 檔案的格式

Babyl 格式的規範。

使用 Rmail 閱讀郵件

Rmail 手冊,包含一些關於 Babyl 語義的資訊。

MMDF 物件

class mailbox.MMDF(path, factory=None, create=True)

MMDF 格式郵箱的 Mailbox 子類。引數 factory 是一個可呼叫物件,它接受一個檔案式訊息表示(其行為如同以二進位制模式開啟)並返回一個自定義表示。如果 factoryNone,則使用 MMDFMessage 作為預設的訊息表示。如果 createTrue,則郵箱在不存在時建立。

MMDF 是一種單檔案郵箱格式,是為多通道備忘錄分發設施(一種郵件傳輸代理)而發明的。每封郵件的格式與 mbox 郵件相同,但前後由包含四個 Control-A ('\001') 字元的行括起來。與 mbox 格式一樣,每封郵件的開頭由一行指示,其前五個字元是“From ”,但儲存郵件時,額外的“From ”出現不會轉換為“>From ”,因為額外的訊息分隔符行可以防止將這些出現誤認為是後續郵件的開頭。

MMDF 實現的一些 Mailbox 方法值得特別注意

get_bytes(key, from_=False)

注意:與其他類相比,此方法有一個額外的引數(from_)。mbox 檔案條目的第一行是 Unix 的“From ”行。如果 from_ 為 False,則檔案中的第一行將被丟棄。

get_file(key, from_=False)

MMDF 例項上呼叫 flush()close() 後使用檔案可能會產生不可預測的結果或引發異常。

注意:與其他類相比,此方法有一個額外的引數(from_)。mbox 檔案條目的第一行是 Unix 的“From ”行。如果 from_ 為 False,則檔案中的第一行將被丟棄。

lock()
unlock()

使用了三種鎖定機制——點鎖定,以及如果可用,flock()lockf() 系統呼叫。

參見

來自 tin 的 mmdf 手冊頁

來自新聞閱讀器 tin 文件的 MMDF 格式規範。

MMDF

一篇描述多通道備忘錄分發設施的維基百科文章。

Message 物件

class mailbox.Message(message=None)

email.message 模組的 Message 子類。mailbox.Message 的子類添加了特定於郵箱格式的狀態和行為。

如果省略 message,新例項將以預設的空狀態建立。如果 messageemail.message.Message 例項,則會複製其內容;此外,如果 messageMessage 例項,則會盡可能地轉換任何特定於格式的資訊。如果 message 是字串、位元組串或檔案,它應包含符合 RFC 2822 的訊息,該訊息將被讀取和解析。檔案應以二進位制模式開啟,但出於向後相容性,也接受文字模式檔案。

子類提供的特定於格式的狀態和行為各不相同,但通常只支援不特定於特定郵箱的屬性(儘管這些屬性可能特定於特定郵箱格式)。例如,單檔案郵箱格式的檔案偏移量和基於目錄的郵箱格式的檔名不會保留,因為它們僅適用於原始郵箱。但諸如郵件是否已被使用者閱讀或標記為重要等狀態會保留,因為它適用於郵件本身。

沒有要求使用 Message 例項來表示使用 Mailbox 例項檢索的訊息。在某些情況下,生成 Message 表示所需的時間和記憶體可能無法接受。對於這種情況,Mailbox 例項還提供字串和檔案式表示,並且在初始化 Mailbox 例項時可以指定自定義訊息工廠。

MaildirMessage 物件

class mailbox.MaildirMessage(message=None)

具有 Maildir 特定行為的訊息。引數 message 的含義與 Message 建構函式相同。

通常,郵件使用者代理應用程式在使用者第一次開啟和關閉郵箱後,會將 new 子目錄中的所有郵件移動到 cur 子目錄,記錄這些郵件是舊的,無論它們是否實際被閱讀。 cur 中的每封郵件的檔名都會新增一個“info”部分來儲存其狀態資訊。(一些郵件閱讀器也可能在 new 中的郵件中新增“info”部分。)“info”部分可以採用兩種形式之一:它可以包含“2,”,後跟一個標準化標誌列表(例如,“2,FR”),或者它可以包含“1,”,後跟所謂的實驗資訊。Maildir 郵件的標準標誌如下:

Flag

含義

說明

D

草稿

撰寫中

F

已標記

標記為重要

P

已透過

已轉發、已重發或已退回

R

已回覆

已回覆

S

已檢視

已讀

T

已刪除

標記為後續刪除

MaildirMessage 例項提供以下方法

get_subdir()

返回“new”(如果郵件應儲存在 new 子目錄中)或“cur”(如果郵件應儲存在 cur 子目錄中)。

備註

郵件通常在郵箱被訪問後從 new 移動到 cur,無論郵件是否已被閱讀。如果 "S" in msg.get_flags()True,則郵件 msg 已被閱讀。

set_subdir(subdir)

設定郵件應儲存在的子目錄。引數 subdir 必須是“new”或“cur”。

get_flags()

返回一個字串,指定當前設定的標誌。如果訊息符合標準 Maildir 格式,結果將是 'D''F''P''R''S''T' 中的零次或一次出現按字母順序串聯。如果未設定任何標誌或“info”包含實驗語義,則返回空字串。

set_flags(flags)

設定由 flags 指定的標誌,並取消設定所有其他標誌。

add_flag(flag)

設定由 flag 指定的標誌,而不更改其他標誌。要一次新增多個標誌,flag 可以是多個字元的字串。無論當前“info”是否包含實驗資訊而非標誌,它都將被覆蓋。

remove_flag(flag)

取消設定由 flag 指定的標誌,而不更改其他標誌。要一次刪除多個標誌,flag 可以是多個字元的字串。如果“info”包含實驗資訊而非標誌,則當前“info”不會被修改。

get_date()

以自紀元以來的秒數表示的浮點數形式返回郵件的投遞日期。

set_date(date)

將郵件的投遞日期設定為 date,這是一個表示自紀元以來的秒數的浮點數。

get_info()

返回包含訊息“info”的字串。這對於訪問和修改實驗性“info”(即,不是標誌列表)非常有用。

set_info(info)

將“info”設定為 info,它應該是一個字串。

當基於 mboxMessageMMDFMessage 例項建立 MaildirMessage 例項時,StatusX-Status 標頭將被省略,併發生以下轉換:

結果狀態

mboxMessageMMDFMessage 狀態

“cur”子目錄

O 標誌

F 標誌

F 標誌

R 標誌

A 標誌

S 標誌

R 標誌

T 標誌

D 標誌

當基於 MHMessage 例項建立 MaildirMessage 例項時,發生以下轉換:

結果狀態

MHMessage 狀態

“cur”子目錄

“unseen”序列

“cur”子目錄和 S 標誌

無“unseen”序列

F 標誌

“flagged”序列

R 標誌

“replied”序列

當基於 BabylMessage 例項建立 MaildirMessage 例項時,發生以下轉換:

結果狀態

BabylMessage 狀態

“cur”子目錄

“unseen”標籤

“cur”子目錄和 S 標誌

無“unseen”標籤

P 標誌

“forwarded”或“resent”標籤

R 標誌

“answered”標籤

T 標誌

“deleted”標籤

mboxMessage 物件

class mailbox.mboxMessage(message=None)

具有 mbox 特定行為的訊息。引數 message 的含義與 Message 建構函式相同。

mbox 郵箱中的訊息儲存在一個檔案中。發件人信封地址和投遞時間通常儲存在以“From ”開頭的行中,該行用於指示訊息的開始,儘管 mbox 實現之間此資料的確切格式存在很大差異。指示訊息狀態的標誌,例如是否已讀或標記為重要,通常儲存在 StatusX-Status 標頭中。

mbox 郵件的傳統標誌如下:

Flag

含義

說明

R

已讀

已讀

O

舊的

先前由 MUA 檢測到

D

已刪除

標記為後續刪除

F

已標記

標記為重要

A

已回覆

已回覆

“R”和“O”標誌儲存在 Status 標頭中,“D”、“F”和“A”標誌儲存在 X-Status 標頭中。這些標誌和標頭通常按所提及的順序出現。

mboxMessage 例項提供以下方法

get_from()

返回一個字串,表示 mbox 郵箱中標記郵件開頭的“From ”行。開頭的“From ”和結尾的換行符被排除。

set_from(from_, time_=None)

將“From ”行設定為 from_,其指定時應不帶開頭的“From ”或結尾的換行符。為方便起見,可以指定 time_,它將被適當格式化並附加到 from_。如果指定了 time_,它應該是一個 time.struct_time 例項,一個適合傳遞給 time.strftime() 的元組,或者 True(使用 time.gmtime())。

get_flags()

返回一個字串,指定當前設定的標誌。如果訊息符合傳統格式,結果將是 'R''O''D''F''A' 中零次或一次出現按以下順序串聯。

set_flags(flags)

設定由 flags 指定的標誌,並取消設定所有其他標誌。引數 flags 應該是 'R''O''D''F''A' 中零次或多次出現以任意順序連線的字串。

add_flag(flag)

設定由 flag 指定的標誌,而不更改其他標誌。要一次新增多個標誌,flag 可以是多個字元的字串。

remove_flag(flag)

取消設定由 flag 指定的標誌,而不更改其他標誌。要一次刪除多個標誌,flag 可以是多個字元的字串。

當基於 MaildirMessage 例項建立 mboxMessage 例項時,會根據 MaildirMessage 例項的投遞日期生成“From ”行,併發生以下轉換:

結果狀態

MaildirMessage 狀態

R 標誌

S 標誌

O 標誌

“cur”子目錄

D 標誌

T 標誌

F 標誌

F 標誌

A 標誌

R 標誌

當基於 MHMessage 例項建立 mboxMessage 例項時,發生以下轉換:

結果狀態

MHMessage 狀態

R 標誌和 O 標誌

無“unseen”序列

O 標誌

“unseen”序列

F 標誌

“flagged”序列

A 標誌

“replied”序列

當基於 BabylMessage 例項建立 mboxMessage 例項時,發生以下轉換:

結果狀態

BabylMessage 狀態

R 標誌和 O 標誌

無“unseen”標籤

O 標誌

“unseen”標籤

D 標誌

“deleted”標籤

A 標誌

“answered”標籤

當基於 MMDFMessage 例項建立 mboxMessage 例項時,“From ”行被複制,所有標誌直接對應:

結果狀態

MMDFMessage 狀態

R 標誌

R 標誌

O 標誌

O 標誌

D 標誌

D 標誌

F 標誌

F 標誌

A 標誌

A 標誌

MHMessage 物件

class mailbox.MHMessage(message=None)

具有 MH 特定行為的訊息。引數 message 的含義與 Message 建構函式相同。

MH 訊息不支援傳統意義上的標記或標誌,但它們支援序列,序列是任意訊息的邏輯分組。一些郵件閱讀程式(儘管不是標準的 mhnmh)以與使用其他格式的標誌大致相同的方式使用序列,如下所示:

序列

說明

未讀

未讀,但此前已被 MUA 檢測到

已回覆

已回覆

已標記

標記為重要

MHMessage 例項提供以下方法

get_sequences()

返回包含此訊息的序列名稱列表。

set_sequences(sequences)

設定包含此訊息的序列列表。

add_sequence(sequence)

sequence 新增到包含此訊息的序列列表中。

remove_sequence(sequence)

從包含此訊息的序列列表中刪除 sequence

當基於 MaildirMessage 例項建立 MHMessage 例項時,發生以下轉換:

結果狀態

MaildirMessage 狀態

“unseen”序列

無 S 標誌

“replied”序列

R 標誌

“flagged”序列

F 標誌

當基於 mboxMessageMMDFMessage 例項建立 MHMessage 例項時,StatusX-Status 標頭被省略,併發生以下轉換:

結果狀態

mboxMessageMMDFMessage 狀態

“unseen”序列

無 R 標誌

“replied”序列

A 標誌

“flagged”序列

F 標誌

當基於 BabylMessage 例項建立 MHMessage 例項時,發生以下轉換:

結果狀態

BabylMessage 狀態

“unseen”序列

“unseen”標籤

“replied”序列

“answered”標籤

BabylMessage 物件

class mailbox.BabylMessage(message=None)

具有 Babyl 特定行為的訊息。引數 message 的含義與 Message 建構函式相同。

某些訊息標籤,稱為 屬性,根據約定具有特殊含義。這些屬性如下:

標籤

說明

未讀

未讀,但此前已被 MUA 檢測到

已刪除

標記為後續刪除

已歸檔

已複製到其他檔案或郵箱

已回覆

已回覆

已轉發

已轉發

已編輯

已由使用者修改

已重發

已重發

預設情況下,Rmail 只顯示可見的標題。BabylMessage 類使用原始標題,因為它們更完整。如果需要,可以顯式訪問可見標題。

BabylMessage 例項提供以下方法

get_labels()

返回訊息上的標籤列表。

set_labels(labels)

將訊息上的標籤列表設定為 labels

add_label(label)

label 新增到訊息上的標籤列表。

remove_label(label)

從訊息上的標籤列表中刪除 label

get_visible()

返回一個 Message 例項,其標題是訊息的可見標題,正文為空。

set_visible(visible)

將訊息的可見標題設定為與 message 中的標題相同。引數 visible 應該是一個 Message 例項,一個 email.message.Message 例項,一個字串,或一個檔案式物件(應該以文字模式開啟)。

update_visible()

BabylMessage 例項的原始標題被修改時,可見標題不會自動修改以對應。此方法按如下方式更新可見標題:每個具有相應原始標題的可見標題被設定為原始標題的值,每個沒有相應原始標題的可見標題被刪除,以及原始標題中存在但可見標題中不存在的任何 DateFromReply-ToToCCSubject 都被新增到可見標題中。

當基於 MaildirMessage 例項建立 BabylMessage 例項時,發生以下轉換:

結果狀態

MaildirMessage 狀態

“unseen”標籤

無 S 標誌

“deleted”標籤

T 標誌

“answered”標籤

R 標誌

“forwarded”標籤

P 標誌

當基於 mboxMessageMMDFMessage 例項建立 BabylMessage 例項時,StatusX-Status 標頭被省略,併發生以下轉換:

結果狀態

mboxMessageMMDFMessage 狀態

“unseen”標籤

無 R 標誌

“deleted”標籤

D 標誌

“answered”標籤

A 標誌

當基於 MHMessage 例項建立 BabylMessage 例項時,發生以下轉換:

結果狀態

MHMessage 狀態

“unseen”標籤

“unseen”序列

“answered”標籤

“replied”序列

MMDFMessage 物件

class mailbox.MMDFMessage(message=None)

具有 MMDF 特定行為的訊息。引數 message 的含義與 Message 建構函式相同。

與 mbox 郵箱中的訊息一樣,MMDF 訊息儲存在以“From ”開頭的初始行中,其中包含發件人地址和投遞日期。同樣,指示訊息狀態的標誌通常儲存在 StatusX-Status 標頭中。

MMDF 訊息的傳統標誌與 mbox 訊息的標誌相同,如下所示:

Flag

含義

說明

R

已讀

已讀

O

舊的

先前由 MUA 檢測到

D

已刪除

標記為後續刪除

F

已標記

標記為重要

A

已回覆

已回覆

“R”和“O”標誌儲存在 Status 標頭中,“D”、“F”和“A”標誌儲存在 X-Status 標頭中。這些標誌和標頭通常按所提及的順序出現。

MMDFMessage 例項提供以下方法,這些方法與 mboxMessage 提供的方法相同:

get_from()

返回一個字串,表示 mbox 郵箱中標記郵件開頭的“From ”行。開頭的“From ”和結尾的換行符被排除。

set_from(from_, time_=None)

將“From ”行設定為 from_,其指定時應不帶開頭的“From ”或結尾的換行符。為方便起見,可以指定 time_,它將被適當格式化並附加到 from_。如果指定了 time_,它應該是一個 time.struct_time 例項,一個適合傳遞給 time.strftime() 的元組,或者 True(使用 time.gmtime())。

get_flags()

返回一個字串,指定當前設定的標誌。如果訊息符合傳統格式,結果將是 'R''O''D''F''A' 中零次或一次出現按以下順序串聯。

set_flags(flags)

設定由 flags 指定的標誌,並取消設定所有其他標誌。引數 flags 應該是 'R''O''D''F''A' 中零次或多次出現以任意順序連線的字串。

add_flag(flag)

設定由 flag 指定的標誌,而不更改其他標誌。要一次新增多個標誌,flag 可以是多個字元的字串。

remove_flag(flag)

取消設定由 flag 指定的標誌,而不更改其他標誌。要一次刪除多個標誌,flag 可以是多個字元的字串。

當基於 MaildirMessage 例項建立 MMDFMessage 例項時,會根據 MaildirMessage 例項的投遞日期生成“From ”行,併發生以下轉換:

結果狀態

MaildirMessage 狀態

R 標誌

S 標誌

O 標誌

“cur”子目錄

D 標誌

T 標誌

F 標誌

F 標誌

A 標誌

R 標誌

當基於 MHMessage 例項建立 MMDFMessage 例項時,發生以下轉換:

結果狀態

MHMessage 狀態

R 標誌和 O 標誌

無“unseen”序列

O 標誌

“unseen”序列

F 標誌

“flagged”序列

A 標誌

“replied”序列

當基於 BabylMessage 例項建立 MMDFMessage 例項時,發生以下轉換:

結果狀態

BabylMessage 狀態

R 標誌和 O 標誌

無“unseen”標籤

O 標誌

“unseen”標籤

D 標誌

“deleted”標籤

A 標誌

“answered”標籤

當基於 mboxMessage 例項建立 MMDFMessage 例項時,“From ”行被複制,所有標誌直接對應:

結果狀態

mboxMessage 狀態

R 標誌

R 標誌

O 標誌

O 標誌

D 標誌

D 標誌

F 標誌

F 標誌

A 標誌

A 標誌

異常

mailbox 模組中定義了以下異常類

exception mailbox.Error

所有其他模組特定異常的基類。

exception mailbox.NoSuchMailboxError

當期望郵箱但未找到時引發,例如在例項化 Mailbox 子類時,路徑不存在(且 create 引數設定為 False),或開啟不存在的資料夾時。

exception mailbox.NotEmptyError

當郵箱不為空但預期為空時引發,例如在刪除包含郵件的資料夾時。

exception mailbox.ExternalClashError

當超出程式控制範圍的某些與郵箱相關的條件導致程式無法繼續時引發,例如無法獲取已被另一個程式持有的鎖,或者唯一生成的檔名已存在時。

exception mailbox.FormatError

當檔案中的資料無法解析時引發,例如 MH 例項嘗試讀取損壞的 .mh_sequences 檔案時。

示例

一個簡單的示例,列印郵箱中所有似乎有趣的郵件的主題

import mailbox
for message in mailbox.mbox('~/mbox'):
    subject = message['subject']       # Could possibly be None.
    if subject and 'python' in subject.lower():
        print(subject)

將所有郵件從 Babyl 郵箱複製到 MH 郵箱,並轉換所有可轉換的格式特定資訊

import mailbox
destination = mailbox.MH('~/Mail')
destination.lock()
for message in mailbox.Babyl('~/RMAIL'):
    destination.add(mailbox.MHMessage(message))
destination.flush()
destination.unlock()

此示例將來自多個郵件列表的郵件分類到不同的郵箱中,注意避免因其他程式併發修改導致的郵件損壞、因程式中斷導致的郵件丟失或因郵箱中格式錯誤的郵件導致的過早終止

import mailbox
import email.errors

list_names = ('python-list', 'python-dev', 'python-bugs')

boxes = {name: mailbox.mbox('~/email/%s' % name) for name in list_names}
inbox = mailbox.Maildir('~/Maildir', factory=None)

for key in inbox.iterkeys():
    try:
        message = inbox[key]
    except email.errors.MessageParseError:
        continue                # The message is malformed. Just leave it.

    for name in list_names:
        list_id = message['list-id']
        if list_id and name in list_id:
            # Get mailbox to use
            box = boxes[name]

            # Write copy to disk before removing original.
            # If there's a crash, you might duplicate a message, but
            # that's better than losing a message completely.
            box.lock()
            box.add(message)
            box.flush()
            box.unlock()

            # Remove original message
            inbox.lock()
            inbox.discard(key)
            inbox.flush()
            inbox.unlock()
            break               # Found destination, so stop looking.

for box in boxes.itervalues():
    box.close()