mailbox
— 以各种格式操作邮箱¶
源代码: Lib/mailbox.py
此模块定义了两个类,Mailbox
和 Message
,用于访问和操作磁盘上的邮箱以及它们包含的消息。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 对应的消息的特定格式信息保持不变。
- 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_string(key)¶
返回与 key 对应的消息的字符串表示形式,如果不存在此消息,则引发
KeyError
异常。该消息会通过email.message.Message
进行处理,将其转换为 7 位干净的表示形式。
- get_file(key)¶
返回与 key 对应的消息的 类文件 表示形式,如果不存在此消息,则引发
KeyError
异常。此类文件对象的行为就像以二进制模式打开一样。此文件一旦不再需要,应将其关闭。注意
与其他消息表示形式不同,类文件 表示形式不一定独立于创建它们的
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 应该是一个 key 到 message 的映射或一个 (key, message) 对的可迭代对象。更新邮箱,以便对于每个给定的 key 和 message,与 key 对应的消息设置为 message,就像使用
__setitem__()
一样。与__setitem__()
一样,每个 key 必须已经对应于邮箱中的一条消息,否则会引发KeyError
异常,因此通常 arg 不应该是一个Mailbox
实例。注意
与字典不同,不支持关键字参数。
- lock()¶
获取对邮箱的独占咨询锁,以便其他进程知道不要修改它。如果锁不可用,则引发
ExternalClashError
。使用的特定锁定机制取决于邮箱格式。在对邮箱的内容进行任何修改之前,您应该始终锁定邮箱。
- unlock()¶
释放邮箱上的锁(如果有)。
- close()¶
刷新邮箱,如有必要则解锁,并关闭所有打开的文件。对于某些
Mailbox
子类,此方法不执行任何操作。
Maildir
对象¶
- class mailbox.Maildir(dirname, factory=None, create=True)¶
Mailbox
的子类,用于 Maildir 格式的邮箱。参数 factory 是一个可调用对象,它接受类文件的消息表示形式(其行为就像以二进制模式打开一样)并返回自定义表示形式。如果 factory 为None
,则使用MaildirMessage
作为默认消息表示形式。如果 create 为True
,则在邮箱不存在时创建邮箱。如果 create 为
True
并且 dirname 路径存在,则会将其视为现有 maildir,而不会尝试验证其目录布局。出于历史原因,dirname 被命名为这样而不是 path。
Maildir 是一种基于目录的邮箱格式,为 qmail 邮件传输代理发明,现在被其他程序广泛支持。Maildir 邮箱中的消息存储在公共目录结构中的单独文件中。这种设计允许多个不相关的程序访问和修改 Maildir 邮箱而不会发生数据损坏,因此不需要文件锁定。
Maildir 邮箱包含三个子目录,即:
tmp
、new
和cur
。消息在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 邮箱的所有更改都会立即应用,因此此方法不执行任何操作。
- close()¶
Maildir
实例不保留任何打开的文件,并且底层邮箱不支持锁定,因此此方法不会执行任何操作。
- get_file(key)¶
根据主机平台的不同,在返回的文件保持打开状态时,可能无法修改或删除底层消息。
参见
- 来自 Courier 的 maildir 手册页
格式的规范。描述了用于支持文件夹的常见扩展。
- 使用 maildir 格式
关于 Maildir 的发明者的说明。包括更新的名称创建方案和关于“info”语义的详细信息。
mbox
对象¶
- class mailbox.mbox(path, factory=None, create=True)¶
用于 mbox 格式邮箱的
Mailbox
的子类。参数 factory 是一个可调用对象,它接受类文件消息表示(其行为如同以二进制模式打开),并返回自定义表示。如果 factory 为None
,则使用mboxMessage
作为默认消息表示。如果 create 为True
,则在邮箱不存在时创建邮箱。mbox 格式是用于在 Unix 系统上存储邮件的经典格式。mbox 邮箱中的所有消息都存储在单个文件中,每条消息的开头都由一行以“From ”开头的行表示。
存在几种 mbox 格式的变体,以解决原始格式中被认为的缺点。为了兼容性,
mbox
实现了原始格式,有时被称为 mboxo。这意味着如果存在 Content-Length 标头,则会被忽略,并且消息正文中任何以“From ”开头的行在存储消息时都会转换为“>From ”,尽管读取消息时“>From ”的出现不会转换为“From ”。由
mbox
实现的某些Mailbox
方法值得特别说明
参见
- 来自 tin 的 mbox 手册页
格式的规范,其中包含有关锁定的详细信息。
- 在 Unix 上配置 Netscape Mail:为什么 Content-Length 格式不好
使用原始 mbox 格式而不是变体的论据。
- “mbox”是几种相互不兼容的邮箱格式的系列
mbox 变体的历史。
MH
对象¶
- class mailbox.MH(path, factory=None, create=True)¶
用于 MH 格式邮箱的
Mailbox
的子类。参数 factory 是一个可调用对象,它接受类文件消息表示(其行为如同以二进制模式打开),并返回自定义表示。如果 factory 为None
,则使用MHMessage
作为默认消息表示。如果 create 为True
,则在邮箱不存在时创建邮箱。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
方法值得特别说明- lock()¶
- unlock()¶
使用了三种锁定机制 - 点锁定,以及(如果可用)
flock()
和lockf()
系统调用。对于 MH 邮箱,锁定邮箱意味着锁定.mh_sequences
文件,并且仅在影响它们的任何操作期间锁定单个消息文件。
- get_file(key)¶
根据主机平台的不同,当返回的文件保持打开状态时,可能无法删除底层消息。
- flush()¶
对 MH 邮箱的所有更改都会立即应用,因此此方法不执行任何操作。
参见
- nmh - 消息处理系统
nmh 的主页,它是原始 mh 的更新版本。
- MH & nmh:用户和程序员的电子邮件
一本关于 mh 和 nmh 的 GPL 许可书籍,其中包含一些关于邮箱格式的信息。
Babyl
对象¶
- class mailbox.Babyl(path, factory=None, create=True)¶
用于 Babyl 格式邮箱的
Mailbox
的子类。参数 factory 是一个可调用对象,它接受一个类似文件的消息表示(其行为类似于以二进制模式打开),并返回一个自定义表示。如果 factory 为None
,则BabylMessage
将用作默认消息表示。如果 create 为True
,则如果邮箱不存在,则会创建该邮箱。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。因此,类似文件的对象真正独立于底层邮箱,但与字符串表示形式相比,不会节省内存。
参见
- 第 5 版 Babyl 文件格式
Babyl 格式的规范。
- 使用 Rmail 读取邮件
Rmail 手册,其中包含一些关于 Babyl 语义的信息。
MMDF
对象¶
- class mailbox.MMDF(path, factory=None, create=True)¶
用于 MMDF 格式邮箱的
Mailbox
的子类。参数 factory 是一个可调用对象,它接受一个类似文件的消息表示(其行为类似于以二进制模式打开),并返回一个自定义表示。如果 factory 为None
,则MMDFMessage
将用作默认消息表示。如果 create 为True
,则如果邮箱不存在,则会创建该邮箱。MMDF 是一种为多通道备忘录分发设施(一种邮件传输代理)发明的单文件邮箱格式。每条消息的格式与 mbox 消息相同,但在前后都用包含四个 Control-A (
'\001'
) 字符的行括起来。与 mbox 格式一样,每条消息的开头由一行开头五个字符为 “From “ 的行表示,但是当存储消息时,额外的 “From “ 不会被转换为 “>From “,因为额外的消息分隔符行可以防止将此类出现误认为是后续消息的开头。MMDF
实现的一些Mailbox
方法值得特别说明。
参见
- 来自 tin 的 mmdf 手册页
来自新闻阅读器 tin 的文档中的 MMDF 格式规范。
- MMDF
一篇描述多通道备忘录分发设施的维基百科文章。
Message
对象¶
- class mailbox.Message(message=None)¶
模块
email.message
的Message
的子类。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,它应该是一个字符串。
当基于 mboxMessage
或 MMDFMessage
实例创建 MaildirMessage
实例时,将省略 Status 和 X-Status 标头,并进行以下转换
结果状态 |
|
---|---|
“cur” 子目录 |
O 标志 |
F 标志 |
F 标志 |
R 标志 |
A 标志 |
S 标志 |
R 标志 |
T 标志 |
D 标志 |
当基于 MHMessage
实例创建 MaildirMessage
实例时,会进行以下转换
结果状态 |
|
---|---|
“cur” 子目录 |
“unseen” 序列 |
“cur” 子目录和 S 标志 |
没有 “unseen” 序列 |
F 标志 |
“flagged” 序列 |
R 标志 |
“replied” 序列 |
当基于 BabylMessage
实例创建 MaildirMessage
实例时,会发生以下转换:
结果状态 |
|
---|---|
“cur” 子目录 |
“unseen” 标签 |
“cur” 子目录和 S 标志 |
没有 “unseen” 标签 |
P 标志 |
“forwarded” 或 “resent” 标签 |
R 标志 |
“answered” 标签 |
T 标志 |
“deleted” 标签 |
mboxMessage
对象¶
- class mailbox.mboxMessage(message=None)¶
具有 mbox 特定行为的消息。参数 message 的含义与
Message
构造函数中的含义相同。mbox 邮箱中的消息存储在单个文件中。发件人的信封地址和发送时间通常存储在以 “From “ 开头的行中,该行用于指示消息的开始,尽管在不同的 mbox 实现中,此数据的确切格式存在很大差异。指示消息状态的标志,例如是否已读取或标记为重要,通常存储在 Status 和 X-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 “ 行,并发生以下转换:
结果状态 |
|
---|---|
R 标志 |
S 标志 |
O 标志 |
“cur” 子目录 |
D 标志 |
T 标志 |
F 标志 |
F 标志 |
A 标志 |
R 标志 |
当基于 MHMessage
实例创建 mboxMessage
实例时,会发生以下转换:
结果状态 |
|
---|---|
R 标志和 O 标志 |
没有 “unseen” 序列 |
O 标志 |
“unseen” 序列 |
F 标志 |
“flagged” 序列 |
A 标志 |
“replied” 序列 |
当基于 BabylMessage
实例创建 mboxMessage
实例时,会发生以下转换:
结果状态 |
|
---|---|
R 标志和 O 标志 |
没有 “unseen” 标签 |
O 标志 |
“unseen” 标签 |
D 标志 |
“deleted” 标签 |
A 标志 |
“answered” 标签 |
当基于 MMDFMessage
实例创建 mboxMessage
实例时,“From “ 行被复制,并且所有标志都直接对应。
结果状态 |
|
---|---|
R 标志 |
R 标志 |
O 标志 |
O 标志 |
D 标志 |
D 标志 |
F 标志 |
F 标志 |
A 标志 |
A 标志 |
MHMessage
对象¶
- class mailbox.MHMessage(message=None)¶
具有 MH 特定行为的消息。参数 message 的含义与
Message
构造函数中的含义相同。MH 消息不支持传统意义上的标记或标志,但它们支持序列,这是任意消息的逻辑分组。一些邮件阅读程序(尽管不是标准的 mh 和 nmh)以与其他格式使用标志非常相似的方式使用序列,如下所示:
序列
解释
未见
未读,但先前被 MUA 检测到
已回复
已回复
已标记
标记为重要
MHMessage
实例提供以下方法:- get_sequences()¶
返回包含此消息的序列名称列表。
- set_sequences(sequences)¶
设置包含此消息的序列列表。
- add_sequence(sequence)¶
将 sequence 添加到包含此消息的序列列表中。
- remove_sequence(sequence)¶
从包含此消息的序列列表中删除 sequence。
当基于 MaildirMessage
实例创建 MHMessage
实例时,会发生以下转换:
结果状态 |
|
---|---|
“unseen” 序列 |
没有 S 标志 |
“replied” 序列 |
R 标志 |
“flagged” 序列 |
F 标志 |
当基于 mboxMessage
或 MMDFMessage
实例创建 MHMessage
实例时,会省略 Status 和 X-Status 标头,并发生以下转换:
结果状态 |
|
---|---|
“unseen” 序列 |
没有 R 标志 |
“replied” 序列 |
A 标志 |
“flagged” 序列 |
F 标志 |
当基于 BabylMessage
实例创建 MHMessage
实例时,会发生以下转换:
结果状态 |
|
---|---|
“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。
- set_visible(visible)¶
将消息的可见标头设置为与 message 中的标头相同。参数 visible 应该是一个
Message
实例,一个email.message.Message
实例,一个字符串或一个类似文件的对象(应该以文本模式打开)。
- update_visible()¶
当
BabylMessage
实例的原始标头被修改时,可见标头不会自动修改以对应。此方法更新可见标头如下:每个具有相应原始标头的可见标头都设置为原始标头的值,每个没有相应原始标头的可见标头都将被删除,并且原始标头中存在但可见标头中不存在的任何 Date、From、Reply-To、To、CC 和 Subject 都将添加到可见标头中。
当基于 MaildirMessage
实例创建 BabylMessage
实例时,会发生以下转换:
结果状态 |
|
---|---|
“unseen” 标签 |
没有 S 标志 |
“deleted” 标签 |
T 标志 |
“answered” 标签 |
R 标志 |
“已转发” 标签 |
P 标志 |
当基于 mboxMessage
或 MMDFMessage
实例创建 BabylMessage
实例时,会省略 Status 和 X-Status 标头,并发生以下转换:
结果状态 |
|
---|---|
“unseen” 标签 |
没有 R 标志 |
“deleted” 标签 |
D 标志 |
“answered” 标签 |
A 标志 |
当基于 MHMessage
实例创建 BabylMessage
实例时,会发生以下转换:
结果状态 |
|
---|---|
“unseen” 标签 |
“unseen” 序列 |
“answered” 标签 |
“replied” 序列 |
MMDFMessage
对象¶
- class mailbox.MMDFMessage(message=None)¶
具有 MMDF 特定行为的消息。参数 message 的含义与
Message
构造函数相同。与 mbox 邮箱中的消息一样,MMDF 消息存储时,发送者的地址和发送日期在以“From ”开头的初始行中。同样,指示消息状态的标志通常存储在 Status 和 X-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 ”行,并发生以下转换:
结果状态 |
|
---|---|
R 标志 |
S 标志 |
O 标志 |
“cur” 子目录 |
D 标志 |
T 标志 |
F 标志 |
F 标志 |
A 标志 |
R 标志 |
当基于 MHMessage
实例创建 MMDFMessage
实例时,会发生以下转换:
结果状态 |
|
---|---|
R 标志和 O 标志 |
没有 “unseen” 序列 |
O 标志 |
“unseen” 序列 |
F 标志 |
“flagged” 序列 |
A 标志 |
“replied” 序列 |
当基于 BabylMessage
实例创建 MMDFMessage
实例时,会发生以下转换:
结果状态 |
|
---|---|
R 标志和 O 标志 |
没有 “unseen” 标签 |
O 标志 |
“unseen” 标签 |
D 标志 |
“deleted” 标签 |
A 标志 |
“answered” 标签 |
当基于 mboxMessage
实例创建 MMDFMessage
实例时,将复制“From ”行,并且所有标志直接对应
结果状态 |
|
---|---|
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¶
当某些超出程序控制范围的邮箱相关条件导致程序无法继续时引发此错误,例如无法获取另一个程序已持有的锁,或者当唯一生成的文件名已存在时。
示例¶
一个简单的示例,打印邮箱中所有看起来有趣的消息的主题
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()