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 迭代器 迭代訊息表示,而不是像預設的 dictionary 迭代器那樣迭代鍵。此外,在迭代期間修改郵箱是安全且明確定義的。迭代器建立後新增到郵箱的訊息將不會被迭代器看到。在迭代器生成之前從郵箱中刪除的訊息將被靜默跳過,但如果隨後刪除了相應的訊息,則使用迭代器中的鍵可能會導致 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。該訊息表示為適當的特定格式的 Message 子類的例項,除非在初始化 Mailbox 例項時指定了自定義訊息工廠。

popitem()

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

update(arg)

引數 arg 應該是一個 keymessage 的對映或一個 (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,則在郵箱不存在時建立郵箱。

如果 createTrue 並且 dirname 路徑存在,則會將其視為現有 maildir,而不會嘗試驗證其目錄佈局。

出於歷史原因,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() 方法,因為訊息的 set_flags()add_flag()remove_flag() 方法所做的更改不會在此處反映,直到呼叫郵箱的 __setitem__() 方法。

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() 方法,因為訊息的 set_info() 方法所做的更改不會在此處反映,直到呼叫郵箱的 __setitem__() 方法。

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 的發明者的說明。包括更新的名稱建立方案和關於“info”語義的詳細資訊。

mbox 物件

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

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

mbox 格式是用於在 Unix 系統上儲存郵件的經典格式。mbox 郵箱中的所有訊息都儲存在單個檔案中,每條訊息的開頭都由一行以“From ”開頭的行表示。

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

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

get_file(key)

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

lock()
unlock()

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

參見

來自 tin 的 mbox 手冊頁

格式的規範,其中包含有關鎖定的詳細資訊。

在 Unix 上配置 Netscape Mail:為什麼 Content-Length 格式不好

使用原始 mbox 格式而不是變體的論據。

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

mbox 變體的歷史。

MH 物件

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

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

MH 是一種基於目錄的郵箱格式,為郵件使用者代理 MH 訊息處理系統發明。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 重新定義郵箱中存在的序列,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)

用於 Babyl 格式郵箱的 Mailbox 的子類。引數 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_file(key)

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

lock()
unlock()

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

參見

來自 tin 的 mmdf 手冊頁

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

MMDF

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

Message 物件

class mailbox.Message(message=None)

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

如果省略 message,則會在預設的空狀態下建立新例項。如果 message 是一個 email.message.Message 例項,則會複製其內容;此外,如果 message 是一個 Message 例項,則會盡可能轉換任何特定於格式的資訊。如果 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 訊息的標準標誌如下

標誌

含義

解釋

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()

將訊息的傳遞日期作為表示自 epoch 以來的秒數的浮點數返回。

set_date(date)

將訊息的傳遞日期設定為 date,一個表示自 epoch 以來的秒數的浮點數。

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 訊息的傳統標誌如下:

標誌

含義

解釋

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 標誌

“已轉發” 標籤

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 訊息的標誌相同,如下所示:

標誌

含義

解釋

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

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

exception mailbox.NotEmptyError

當郵箱不為空但預期為空時引發此錯誤,例如刪除包含訊息的資料夾時。

異常 mailbox.ExternalClashError

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

異常 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()