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
迭代器 迭代邮件表示形式,而不是像默认的字典
迭代器那样迭代键。此外,在迭代期间修改邮箱是安全且定义明确的。创建迭代器后添加到邮箱中的邮件将不会被迭代器看到。在迭代器产生邮件之前从邮箱中删除的邮件将被静默跳过,尽管如果随后删除了相应的邮件,则使用迭代器中的键可能会导致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)¶
将与 key 对应的邮件替换为 message。如果尚无邮件与 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*。除非在初始化
Mailbox
实例时指定了自定义消息工厂,否则消息将表示为相应的格式特定Message
子类的实例。
- popitem()¶
返回一个任意的 ( *key*, *message* ) 对,其中 *key* 是一个键,*message* 是一个消息表示形式,并删除对应的消息。如果邮箱为空,则引发
KeyError
异常。除非在初始化Mailbox
实例时指定了自定义消息工厂,否则消息将表示为相应的格式特定Message
子类的实例。
- update(arg)¶
参数 *arg* 应为 *key*-to-*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)¶
用于 Maildir 格式邮箱的
Mailbox
子类。参数 factory 是一个可调用对象,它接受类似文件的邮件表示形式(其行为类似于以二进制模式打开)并返回自定义表示形式。如果 factory 为None
,则使用MaildirMessage
作为默认邮件表示形式。如果 create 为True
,则在邮箱不存在时创建它。如果 create 为
True
且 dirname 路径存在,则将其视为现有邮件目录,而不会尝试验证其目录布局。由于历史原因,dirname 被命名为此名称而不是 path。
Maildir 是一种基于目录的邮箱格式,是为 qmail 邮件传输代理发明的,现在被其他程序广泛支持。Maildir 邮箱中的邮件存储在公共目录结构中的单独文件中。这种设计允许多个不相关的程序访问和修改 Maildir 邮箱而不会损坏数据,因此不需要文件锁定。
Maildir 邮箱包含三个子目录,即:
tmp
、new
和cur
。邮件会在tmp
子目录中短暂创建,然后移动到new
子目录以完成传递。邮件用户代理随后可以将邮件移动到cur
子目录,并将有关邮件状态的信息存储在其文件名的特殊“信息”部分中。还支持 Courier 邮件传输代理引入的文件夹样式。如果主邮箱的任何子目录的名称中的第一个字符为
'.'
,则该子目录被视为文件夹。文件夹名称由Maildir
表示,不带前导'.'
。每个文件夹本身就是一个 Maildir 邮箱,但不应包含其他文件夹。相反,逻辑嵌套使用'.'
来分隔级别,例如“Archived.2005.07”。- colon¶
Maildir 规范要求在某些邮件文件名中使用冒号 (
':'
)。但是,某些操作系统不允许在文件名中使用此字符。如果希望在这种操作系统上使用类似 Maildir 的格式,则应指定另一个字符来代替。感叹号 ('!'
) 是一个流行的选择。例如import mailbox mailbox.Maildir.colon = '!'
也可以在每个实例的基础上设置
colon
属性。
Maildir
实例具有Mailbox
的所有方法,以及以下方法- list_folders()¶
返回所有文件夹名称的列表。
- get_folder(folder)¶
返回一个表示名称为 folder 的文件夹的
Maildir
实例。如果文件夹不存在,则引发NoSuchMailboxError
异常。
- add_folder(folder)¶
创建一个名称为 folder 的文件夹,并返回一个表示它的
Maildir
实例。
- remove_folder(folder)¶
删除名称为 folder 的文件夹。如果文件夹包含任何邮件,则会引发
NotEmptyError
异常,并且不会删除该文件夹。
- clean()¶
从邮箱中删除在过去 36 小时内未访问过的临时文件。Maildir 规范指出,邮件阅读程序应该偶尔这样做。
由
Maildir
实现的一些Mailbox
方法值得特别说明- add(message)¶
- __setitem__(key, message)¶
- update(arg)¶
警告
这些方法根据当前进程 ID 生成唯一的文件名。使用多个线程时,除非协调线程以避免使用这些方法同时操作同一个邮箱,否则可能会发生未检测到的名称冲突并导致邮箱损坏。
- flush()¶
对 Maildir 邮箱的所有更改都会立即应用,因此此方法不执行任何操作。
- close()¶
Maildir
实例不保留任何打开的文件,并且底层邮箱不支持锁定,因此此方法不执行任何操作。
- get_file(key)¶
根据主机平台的不同,在返回的文件保持打开状态时,可能无法修改或删除底层邮件。
参见
- 来自 Courier 的 maildir 联机帮助页
格式规范。描述了用于支持文件夹的常见扩展。
- 使用 maildir 格式
其发明者关于 Maildir 的注释。包括更新的名称创建方案和“信息”语义的详细信息。
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
的所有方法- list_folders()¶
返回所有文件夹名称的列表。
- get_folder(folder)¶
返回一个表示名称为 folder 的文件夹的
MH
实例。如果文件夹不存在,则引发NoSuchMailboxError
异常。
- add_folder(folder)¶
创建一个名称为 folder 的文件夹,并返回一个表示它的
MH
实例。
- remove_folder(folder)¶
删除名称为 folder 的文件夹。如果文件夹包含任何邮件,则会引发
NotEmptyError
异常,并且不会删除该文件夹。
- get_sequences()¶
返回一个字典,其中包含映射到键列表的序列名称。如果没有序列,则返回空字典。
- set_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)¶
Mailbox
的子类,用于 Babyl 格式的邮箱。参数 *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 与文件的 API 相同。因此,类似文件的对象实际上独立于底层邮箱,但在内存方面与字符串表示形式相比没有节省。
参见
- 版本 5 Babyl 文件的格式
Babyl 格式的规范。
- 使用 Rmail 阅读邮件
Rmail 手册,其中包含一些有关 Babyl 语义的信息。
MMDF
对象¶
- class mailbox.MMDF(path, factory=None, create=True)¶
Mailbox
的子类,用于 MMDF 格式的邮箱。参数 *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()¶
以表示自纪元以来的秒数的浮点数形式返回邮件的传递日期。
- set_date(date)¶
将邮件的传递日期设置为 date,这是一个表示自纪元以来的秒数的浮点数。
- 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
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 可以是包含多个字符的字符串。
结果状态 |
当根据 |
---|---|
R 标志 |
S 标志 |
O 标志 |
“cur” 子目录 |
D 标志 |
T 标志 |
F 标志 |
F 标志 |
A 标志 |
R 标志 |
结果状态 |
|
---|---|
当根据 |
无 “unseen” 序列 |
O 标志 |
“unseen” 序列 |
F 标志 |
“flagged” 序列 |
A 标志 |
“replied” 序列 |
R 标志和 O 标志
结果状态 |
|
---|---|
当根据 |
无 “unseen” 标签 |
O 标志 |
“unseen” 标签 |
D 标志 |
“deleted” 标签 |
A 标志 |
“answered” 标签 |
当根据 BabylMessage
实例创建 mboxMessage
实例时,会进行以下转换
结果状态 |
当根据 |
---|---|
R 标志 |
R 标志 |
O 标志 |
O 标志 |
D 标志 |
D 标志 |
F 标志 |
F 标志 |
A 标志 |
A 标志 |
MMDFMessage
状态
- class mailbox.MHMessage(message=None)¶
具有 MH 特定行为的消息。参数 message 与
Message
构造函数具有相同的含义。MH 消息不支持传统意义上的标记或标志,但它们支持序列,序列是任意消息的逻辑分组。一些邮件阅读程序(尽管不是标准的 mh 和 nmh)使用序列的方式与其他格式使用标志的方式非常相似,如下所示
序列
说明
unseen
未读,但先前已被 MUA 检测到
replied
已回复
flagged
标记为重要
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
构造函数具有相同的含义。按照惯例,某些消息标签(称为属性)被定义为具有特殊含义。属性如下
标签
说明
unseen
未读,但先前已被 MUA 检测到
deleted
标记为随后删除
filed
已复制到另一个文件或邮箱
answered
已回复
forwarded
已转发
edited
用户修改
resent
已转发
默认情况下,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 标志 |
“forwarded” 标签 |
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
D
标记为随后删除
F
已标记
标记为重要
已删除
A
已回复
已回复
MMDFMessage
实例提供以下方法,这些方法与mboxMessage
提供的方法相同
当根据 MaildirMessage
实例创建 MMDFMessage
实例时,将根据 MaildirMessage
实例的发送日期生成“From”行,并进行以下转换
结果状态 |
当根据 |
---|---|
R 标志 |
S 标志 |
O 标志 |
“cur” 子目录 |
D 标志 |
T 标志 |
F 标志 |
F 标志 |
A 标志 |
R 标志 |
当根据 MHMessage
实例创建 MMDFMessage
实例时,将进行以下转换
结果状态 |
|
---|---|
当根据 |
无 “unseen” 序列 |
O 标志 |
“unseen” 序列 |
F 标志 |
“flagged” 序列 |
A 标志 |
“replied” 序列 |
当根据 BabylMessage
实例创建 MMDFMessage
实例时,将进行以下转换
结果状态 |
|
---|---|
当根据 |
无 “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¶
当邮箱不为空但预期为空时引发,例如在删除包含消息的文件夹时引发。
- exception 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()