在线文档教程
Python

mailbox

mailbox — Manipulate mailboxes in various formats

该模块定义了两类,Mailbox并且Message,用于访问和操作的磁盘上的邮箱和它们所包含的消息。Mailbox提供从键到消息的字典式映射。Message扩展email.message模块的Message类与格式特定的状态和行为。支持的邮箱格式是Maildir,mbox,MH,Babyl和MMDF。

1.邮箱对象

class mailbox.Mailbox

邮箱,可能会被检查和修改。

所述Mailbox类定义了一个接口,并且不旨在被实例化。相反,特定于格式的子类应该从中继承,Mailbox并且您的代码应该实例化特定的子类。

Mailbox接口是类似于字典的,与对应于消息的小键。密钥由Mailbox它们将被使用的实例发布,并且仅对该Mailbox实例有意义。即使相应的消息被修改,一个密钥也会继续识别消息,例如通过用另一个消息替换它。

消息可以被添加到Mailbox使用set-类似方法实例add(),并使用去除del语句或设定等的方法remove()discard()

Mailbox接口语义在一些值得注意的方面与字典语义不同。每次请求消息时,都会Message根据邮箱的当前状态生成新的表示(通常为实例)。同样,当消息被添加到Mailbox实例时,所提供的消息表示的内容被复制。在任何情况下都不是对Mailbox实例保留的消息表示的引用。

默认Mailbox迭代器遍历消息表示,而不是默认字典迭代器的键。而且,在迭代过程中修改邮箱是安全和明确的。迭代器创建后添加到邮箱的消息将不会被迭代器看到。在迭代器产生它们之前从邮箱中删除的邮件将被静静地跳过,尽管KeyError如果随后删除相应的消息,使用迭代器中的密钥可能会导致异常。

警告

修改可能被其他进程同时更改的邮箱时要非常谨慎。用于此类任务的最安全邮箱格式是Maildir; 尽量避免使用mbox等单文件格式进行并发写入。如果您要修改邮箱,则必须在读取文件中的任何邮件或通过添加或删除邮件进行任何更改之前调用lock()unlock()方法锁定邮箱。无法锁定邮箱会导致丢失邮件或损坏整个邮箱。

Mailbox 实例具有以下方法:

add(message)

邮件添加到邮箱并返回已分配给它的密钥。

参数消息可以是Message实例,email.message.Message实例,字符串或文件类对象(应该在文本模式下打开)。如果消息是适当的格式特定的Message子类的mboxMessage实例(例如,如果它是一个实例并且这是一个mbox实例),则使用其格式特定的信息。否则,将使用针对格式特定信息的合理默认值。

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

从邮箱中删除与密钥对应的消息。

如果不存在这样的消息,KeyError则如果该方法被调用为remove()或者__delitem__()但如果该方法被调用时不引发异常则会引发异常discard()discard()如果底层邮箱格式支持其他进程的并发修改,则该行为可能是首选。

__setitem__(key, message)

消息替换对应于密钥消息KeyError如果没有消息已经与密钥对应,则引发异常。

与之一样add(),参数消息可能是Message实例,email.message.Message实例,字符串或类似文件的对象(应该以文本模式打开)。如果消息是适当的格式特定的Message子类的mboxMessage实例(例如,如果它是一个实例并且这是一个mbox实例),则使用其格式特定的信息。否则,当前对应于密钥消息的格式特定信息保持不变。

iterkeys()keys()

如果调用as iterkeys(),则返回所有键的迭代器;如果调用as ,则返回键列表keys()

itervalues()__iter__()values()

如果调用为itervalues()__iter__(),则返回所有消息的表示形式的迭代器,或者如果调用为,则返回此类表示形式的列表values()Message除非在Mailbox实例初始化时指定了自定义消息工厂,否则这些消息将表示为适当的格式特定的子类的实例。

注意

__iter__()字典的行为不同于字典,它们遍历密钥。

iteritems()items()

通过(消息)对返回一个迭代器,其中key是一个message是一个消息表示形式,如果调用为,则iteritems()返回一个这样的对的列表items()Message除非在Mailbox实例初始化时指定了自定义消息工厂,否则这些消息将表示为适当的格式特定的子类的实例。

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

返回对应于的消息的表示。如果不存在这样的消息,默认情况下,如果该方法被调用的返回get()以及KeyError如果该方法被称为引发异常__getitem__()。该消息表示为适当格式特定Message子类的实例,除非在Mailbox实例初始化时指定了自定义消息工厂。

get_message(key)

将对应于key的消息的表示形式作为特定格式的Message子类的实例返回,或者KeyError如果不存在此类消息,则引发异常。

get_string(key)

返回对应于的消息的字符串表示形式,或者KeyError如果不存在此类消息,则引发异常。

get_file(key)

返回与密钥对应的消息的类文件表示,或者KeyError如果不存在此类消息则引发异常。类文件对象的行为就好像以二进制模式打开一样。该文件在不再需要时应该关闭。

注意

与消息的其他表示形式不同,类似文件的表示形式不一定独立于Mailbox创建它们的实例或底层邮箱。每个子类都提供更具体的文档。

has_key(key)__contains__(key)

如果对应于消息,则返回True,否则返回False

__len__()

返回邮箱中的邮件数量。

clear()

删除邮箱中的所有邮件。

pop(key[, default])

返回与密钥对应的消息表示并删除该消息。如果不存在这样的消息,则返回默认值,否则引发KeyError异常。该消息表示为适当格式特定Message子类的实例,除非在Mailbox实例初始化时指定了自定义消息工厂。

popitem()

返回任意(密钥消息)对,其中密钥密钥消息消息表示,并删除相应的消息。如果邮箱为空,则引发KeyError异常。该消息表示为适当格式特定Message子类的实例,除非在Mailbox实例初始化时指定了自定义消息工厂。

update(arg)

参数ARG应该是一个 -到- 消息映射或(可迭代消息)对。更新邮箱,以便对于每个给定的密钥消息,将与密钥相对应的消息设置为消息,就像通过使用一样__setitem__()。同样__setitem__(),每个密钥必须已经对应邮箱中的消息,否则KeyError会引发异常,所以通常arg不是Mailbox实例。

注意

与字典不同,不支持关键字参数。

flush()

将任何挂起的更改写入文件系统。对于某些Mailbox子类,变更总是立即写入,flush()并且什么也不做,但是您仍应养成调用此方法的习惯。

lock()

获取邮箱上的独家咨询锁,以便其他进程知道不要修改它。ExternalClashError如果锁不可用,则引发An 。使用的特定锁定机制取决于邮箱格式。在对其内容进行任何修改之前,您应始终锁定邮箱。

unlock()

释放邮箱上的锁,如果有的话。

close()

冲洗邮箱,如有必要将其解锁,然后关闭所有打开的文件。对于某些Mailbox子类,此方法什么都不做。

1.1. Maildir

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

MailboxMaildir格式邮箱的子类。参数工厂是一个可调用的对象,它接受类似文件的消息表示(其行为如同以二进制模式打开)并返回一个自定义表示。如果工厂NoneMaildirMessage则用作默认消息表示。如果创建True,如果它不存在的邮箱已创建

这是由于历史原因,出厂默认rfc822.Message目录名被命名为这样的,而不是路径。对于Maildir像其他Mailbox子类的实例那样行为的实例,请将工厂设置为None

Maildir是一种基于目录的邮箱格式,为qmail邮件传输代理发明,现在已被其他程序广泛支持。Maildir邮箱中的邮件存储在通用目录结构中的单独文件中。这种设计允许Maildir邮箱被多个不相关的程序访问和修改,而不会造成数据损坏,因此不需要文件锁定。

Maildir的邮箱包含三个子目录,分别为:tmpnew,和cur。消息暂时在tmp子目录中创建,然后移至new子目录以完成交付。邮件用户代理可能随后将邮件移动到cur子目录,并将有关邮件状态的信息存储在附加到其文件名的特殊“信息”部分中。

由Courier邮件传输代理引入的样式文件夹也受支持。如果'.'是其名称中的第一个字符,主邮箱的任何子目录都被视为一个文件夹。文件夹名称由Maildir没有前导的表示'.'。每个文件夹本身都是Maildir邮箱,但不应包含其他文件夹。相反,逻辑嵌套表示使用'.'分隔层,例如“Archived.2005.07”。

注意

Maildir规范要求':'在某些消息文件名中使用冒号()。但是,某些操作系统不允许在文件名中使用此字符。如果您希望在此类操作系统上使用类似Maildir的格式,则应该指定另一个字符来代替。感叹号('!')是一种流行的选择。例如:

import mailbox mailbox.Maildir.colon = '!'

colon属性也可以基于每个实例来设置。

MaildirMailbox除了以下内容,实例还具有所有的方法:

list_folders()

返回所有文件夹的名称列表。

get_folder(folder)

返回一个Maildir表示名称为folder的文件夹的实例。一NoSuchMailboxError,如果文件夹不存在异常。

add_folder(folder)

创建一个名称为folder的文件夹并返回一个Maildir代表它的实例。

remove_folder(folder)

删除名称为文件夹的文件夹。如果该文件夹包含任何消息,NotEmptyError则会引发异常并且该文件夹不会被删除。

clean()

从过去36小时内未访问过的邮箱中删除临时文件。Maildir规范说邮件阅读程序偶尔会这样做。

一些Mailbox方法的实施Maildir值得特别注意:

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

警告

这些方法根据当前的进程ID生成唯一的文件名。在使用多个线程时,可能会发生未检测到的名称冲突,并导致邮箱损坏,除非协调线程以避免使用这些方法同时操作同一个邮箱。

flush()

对Maildir邮箱的所有更改都立即应用,因此此方法不会执行任何操作。

lock()unlock()

Maildir邮箱不支持(或需要)锁定,所以这些方法什么也不做。

close()

Maildir 实例不保留任何打开的文件,并且底层邮箱不支持锁定,所以此方法不会执行任何操作。

get_file(key)

根据主机平台的不同,当返回的文件保持打开状态时,可能无法修改或删除基础消息。

1.2. mbox

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

Mailbox用于mbox格式邮箱的子类。参数工厂是一个可调用的对象,它接受类似文件的消息表示(其行为如同以二进制模式打开)并返回一个自定义表示。如果工厂NonemboxMessage则用作默认消息表示。如果创建True,如果它不存在的邮箱已创建

mbox格式是在Unix系统上存储邮件的经典格式。mbox邮箱中的所有邮件都存储在一个文件中,每个邮件的开头由前五个字符为“From”的行指示。

存在几种mbox格式的变体来解决原来的缺陷。为了兼容性,mbox实现了原始格式,有时称为mboxo。这意味着Content-Length标题(如果存在的话)被忽略,并且在消息体中的行的开始处任何出现的“From”都被转换为“> From”,当存储消息时,尽管出现“> From “在阅读邮件时不会转换为”发件人“。

一些Mailbox方法的实施mbox值得特别注意:

get_file(key)

使用文件调用后flush()close()mbox实例可能产生不可预测的结果或引发异常。

lock()unlock()

使用三种锁定机制 - 点锁定和(如果可用)flock()lockf()系统调用。

1.3. MH

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

MailboxMH格式邮箱的子类。参数工厂是一个可调用的对象,它接受类似文件的消息表示(其行为如同以二进制模式打开)并返回一个自定义表示。如果工厂NoneMHMessage则用作默认消息表示。如果创建True,如果它不存在的邮箱已创建

MH是一种基于目录的邮箱格式,是为邮件用户代理MH Message Handling System发明的。MH邮箱中的每封邮件都驻留在自己的文件中。除邮件外,MH邮箱还可能包含其他MH邮箱(称为文件夹)。文件夹可能无限期地嵌套。MH邮箱也支持序列,这些序列被命名为用于在逻辑上对消息进行分组而不移动到子文件夹的列表。序列.mh_sequences在每个文件夹中调用的文件中定义。

MH类操纵MH邮箱,但它并不试图模拟所有的MH的行为。特别是,它不会修改,也不受mh用于存储其状态和配置的文件context.mh_profile文件的影响。

MHMailbox除了以下内容,实例还具有所有的方法:

list_folders()

返回所有文件夹的名称列表。

get_folder(folder)

返回MH表示名称为文件夹文件夹的实例。一NoSuchMailboxError,如果文件夹不存在异常。

add_folder(folder)

创建一个名称为folder的文件夹并返回一个MH代表它的实例。

remove_folder(folder)

删除名称为文件夹的文件夹。如果该文件夹包含任何消息,NotEmptyError则会引发异常并且该文件夹不会被删除。

get_sequences()

返回映射到键列表的序列名称字典。如果没有序列,则返回空字典。

set_sequences(sequences)

根据序列重新定义邮箱中存在的序列,映射到键列表的名称字典(如返回的)get_sequences()

pack()

根据需要重命名邮箱中的邮件以消除编号中的空白。序列表中的条目会相应更新。

注意

已经发行的密钥通过此操作失效,不应随后使用。

一些Mailbox方法的实施MH值得特别注意:

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

这些方法立即删除该消息。不使用通过在其名称前面加逗号来标记消息以供删除的MH惯例。

lock()unlock()

使用三种锁定机制 - 点锁定和(如果可用)flock()lockf()系统调用。对于MH邮箱,锁定邮箱意味着锁定.mh_sequences文件,并且仅在影响它们的任何操作期​​间锁定单个邮件文件。

get_file(key)

根据主机平台的不同,当返回的文件保持打开状态时,可能无法删除底层消息。

flush()

对MH邮箱的所有更改都立即应用,因此此方法不起作用。

close()

MH实例不保留任何打开的文件,所以此方法等同于unlock()

1.4. Babyl

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

MailboxBabyl格式邮箱的子类。参数工厂是一个可调用的对象,它接受类似文件的消息表示(其行为如同以二进制模式打开)并返回一个自定义表示。如果工厂NoneBabylMessage则用作默认消息表示。如果创建True,如果它不存在的邮箱已创建

Babyl是由Emacs附带的Rmail邮件用户代理使用的单一文件邮箱格式。消息的开头由包含两个字符Control-Underscore('\037')和Control-L('\014')的行表示。消息的结尾由下一条消息的开始指示,或者在最后一条消息的情况下,包含一个Control-Underscore('\037')字符的行。

Babyl邮箱中的邮件有两组标题,原始标题和所谓的可见标题。可见标题通常是原始标题的一个子集,已被重新格式化或删节以获得更多吸引力。Babyl邮箱中的每封邮件也都有一个附带的标签列表或用于记录有关邮件的额外信息的短字符串,并且邮箱中找到的所有用户定义标签列表都保存在Babyl选项部分。

BabylMailbox除了以下内容,实例还具有所有的方法:

get_labels()

返回邮箱中使用的所有用户定义标签的名称列表。

注意

检查实际消息以确定邮箱中存在哪些标签,而不是查阅Babyl选项部分中的标签列表,但每当邮箱被修改时都会更新Babyl部分。

一些Mailbox方法的实施Babyl值得特别注意:

get_file(key)

在Babyl邮箱中,邮件的标题不会与邮件正文连续存储。要生成类似文件的表示形式,标题和正文将一起复制到StringIO实例中(来自StringIO模块),该实例具有与文件相同的API。因此,文件类对象确实独立于底层邮箱,但与字符串表示形式相比,不会节省内存。

lock()unlock()

使用三种锁定机制 - 点锁定和(如果可用)flock()lockf()系统调用。

1.5. MMDF

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

MailboxMMDF格式邮箱的子类。参数工厂是一个可调用的对象,它接受类似文件的消息表示(其行为如同以二进制模式打开)并返回一个自定义表示。如果工厂NoneMMDFMessage则用作默认消息表示。如果创建True,如果它不存在的邮箱已创建

MMDF是为多渠道备忘录分发机构(邮件传输代理)发明的单一文件邮箱格式。每条消息的格式与mbox消息相同,但在包含四个Control-A('\001')字符的行之前和之后括起来。与mbox格式一样,每条消息的开头都用前五个字符为“From”的行来表示,但由于额外的消息分隔符行阻止了,所以当存储消息时,附加出现的“From”不会转换为“> From”将这种情况误认为后续消息的开始。

一些Mailbox方法的实施MMDF值得特别注意:

get_file(key)

使用文件调用后flush()close()MMDF实例可能产生不可预测的结果或引发异常。

lock()unlock()

使用三种锁定机制 - 点锁定和(如果可用)flock()lockf()系统调用。

2.消息对象

class mailbox.Message([message])

email.message模块的一个子类Messagemailbox.Message添加邮箱格式特定状态和行为的子类。

如果省略消息,则新实例将以默认的空状态创建。如果消息是一个email.message.Message实例,则其内容被复制; 此外,如果消息Message实例,则尽可能转换任何特定于格式的信息。如果消息是一个字符串或文件,它应该包含一个RFC 2822兼容消息,该消息被读取和解析。

子类提供的特定于格式的状态和行为有所不同,但通常情况下,只有不支持特定邮箱的属性(尽管推测这些属性是特定于特定邮箱格式的)。例如,单个文件邮箱格式的文件偏移量和基于目录的邮箱格式的文件名不会保留,因为它们仅适用于原始邮箱。但是,诸如消息是否被用户读取或标记为重要的状态被保留,因为它适用于消息本身。

没有要求Message使用Mailbox实例来表示使用实例检索的消息。在某些情况下,生成Message表示所需的时间和内存可能不可接受。对于这种情况,Mailbox实例还提供字符串和文件类型的表示,并且可以在Mailbox实例初始化时指定自定义消息工厂。

2.1. MaildirMessage

class mailbox.MaildirMessage([message])

具有Maildir特定行为的消息。参数消息的含义与Message构造函数相同。

通常,邮件用户代理应用程序会在用户第一次打开并关闭邮箱后,将new子目录中的所有邮件移动到cur子目录,并记录邮件是否旧,无论它们是否已被实际读取。每条消息cur都有一个“信息”部分添加到其文件名中,以存储有关其状态的信息。(某些邮件阅读器也可能为信息添加“信息”部分new。)“信息”部分可以采取两种形式之一:它可以包含“2”,后跟一系列标准化标记(例如“2,FR “)或者它可能包含”1“,后面跟着所谓的实验信息。Maildir消息的标准标志如下:

标志含义说明
d草案在构图下
F标记标记为重要
P通过转发,重发或反弹
[R回答已回复
小号
Ť丢弃标记为随后删除

MaildirMessage 实例提供以下方法:

get_subdir()

返回“新”(如果消息应该存储在new子目录中)或“cur”(如果消息应该存储在cur子目录中)。

注意

消息通常是从移动newcur后其邮箱被访问,无论是否该消息已被阅读。msg如果"S" in msg.get_flags()是,则读取消息True

set_subdir(subdir)

设置消息应存储在的子目录中。参数subdir必须是“新”或“当前”。

get_flags()

返回一个字符串,指定当前设置的标志。如果该消息与标准的Maildir格式符合,其结果是在零字母顺序或每一个的发生级联'D''F''P''R''S',和'T'。如果没有设置标志或“info”包含实验性语义,则返回空字符串。

set_flags(flags)

设置由标志指定的标志并取消设置所有其他标志

add_flag(flag)

设置标志指定的标志而不更改其他标志。要一次添加多个标志标志可能是一串多于一个字符。当前的“信息”被覆盖,不管它是否包含实验信息而不是标记。

remove_flag(flag)

取消设置标志指定的标志而不更改其他标志。要一次删除多个标志标志可能是一串多于一个字符。如果“信息”包含实验信息而不是标记,则当前的“信息”不会被修改。

get_date()

将消息的交付日期作为表示自时代以来秒数的浮点数返回。

set_date(date)

将消息的交付日期设置为日期,这是自纪元以来表示秒数的浮点数。

get_info()

返回包含消息“信息”的字符串。这对于访问和修改实验性的“信息”(即不是标志列表)很有用。

set_info(info)

将“info”设置为info,它应该是一个字符串。

当一个MaildirMessage是基于一个创建的实例mboxMessageMMDFMessage实例中,状态X-状态标头省略,下面的转换发生:

结果状态mboxMessage或MMDFMessage状态
“cur”子目录O标志
F旗F标志
R标志A标志
S旗R标志
T旗D标志

当基于MaildirMessage实例创建MHMessage实例时,会发生以下转换:

结果状态MHMessage状态
“cur”子目录“看不见的”序列
“cur”子目录和S标志没有“看不见”的序列
F标志“标记”序列
R标志“回答”了序列

当基于MaildirMessage实例创建BabylMessage实例时,会发生以下转换:

结果状态BabylMessage状态
“cur”子目录“看不见”的标签
“cur”子目录和S标志没有“看不见”的标签
P标志“转发”或“重发”标签
R标志“回答”了标签
T标志“已删除”标签

2.2. mboxMessage

class mailbox.mboxMessage([message])

具有特定于mbox的行为的消息。参数消息的含义与Message构造函数相同。

mbox邮箱中的邮件一起存储在单个文件中。发件人的信封地址和发送时间通常存储在一个以“From”开头的行中,该行用于指示邮件的开始,尽管mbox实现中该数据的确切格式有很大差异。指示消息状态的标志,例如它是否被读取或标记为重要,通常存储在StatusX-Status标题中。

用于mbox消息的常规标志如下所示:

含义说明
[R
以前由MUA检测到
d删除标记为随后删除
F标记标记为重要
A回答已回复

“R”和“O”标志存储在状态标题中,“D”,“F”和“A”标志存储在X状态标题中。标志和标题通常以提到的顺序出现。

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)

设置由标志指定的标志并取消设置所有其他标志。参数标志应当在零个或多个的每一个的任何顺序串联'R''O''D''F',和'A'

add_flag(flag)

设置标志指定的标志而不更改其他标志。要一次添加多个标志标志可能是一串多于一个字符。

remove_flag(flag)

取消设置标志指定的标志而不更改其他标志。要一次删除多个标志标志可能是一串多于一个字符。

当基于mboxMessage实例创建MaildirMessage实例时,将根据MaildirMessage实例的交付日期生成“发件人”行,并进行以下转换:

结果状态MaildirMessage状态
R标志S标志
O标志“cur”子目录
D标志T标志
F标志F标志
A标志R标志

当基于mboxMessage实例创建MHMessage实例时,会发生以下转换:

结果状态MHMessage状态
R标志和O标志没有“看不见”的序列
O标志“看不见的”序列
F标志“标记”序列
A标志“回答”了序列

当基于mboxMessage实例创建BabylMessage实例时,会发生以下转换:

结果状态BabylMessage状态
R标志和O标志没有“看不见”的标签
O标志“看不见”的标签
D标志“已删除”标签
A标志“回答”了标签

当基于Message实例创建MMDFMessage实例时,“From”行被复制,所有标志直接对应:

结果状态MMDFMessage状态
R标志R标志
O标志O标志
D标志D标志
F标志F标志
A标志A标志

2.3. MHMessage

class mailbox.MHMessage([message])

具有MH特定行为的消息。参数消息的含义与Message构造函数相同。

MH消息不支持传统意义上的标记或标志,但它们确实支持序列,它们是任意消息的逻辑分组。某些邮件阅读程序(尽管不是标准的mhnmh)使用序列的方式与标志与其他格式的使用方式大致相同,如下所示:

序列说明
看不见没有阅读,但以前由MUA检测到
回答已回复
已标记标记为重要

MHMessage 实例提供以下方法:

get_sequences()

返回包含此消息的序列名称列表。

set_sequences(sequences)

设置包含此消息的序列列表。

add_sequence(sequence)

序列添加到包含此消息的序列列表中。

remove_sequence(sequence)

从包含此消息的序列列表中删除序列

当基于MHMessage实例创建MaildirMessage实例时,会发生以下转换:

结果状态MaildirMessage状态
“看不见的”序列没有S标志
“回答”了序列R标志
“标记”序列F标志

当一个MHMessage是基于一个创建的实例mboxMessageMMDFMessage实例中,状态X-状态标头省略,下面的转换发生:

结果状态mboxMessage或MMDFMessage状态
“看不见的”序列没有R标志
“回答”了序列A标志
“标记”序列F标志

当基于MHMessage实例创建BabylMessage实例时,会发生以下转换:

结果状态BabylMessage状态
“看不见的”序列“看不见”的标签
“回答”了序列“回答”了标签

2.4. BabylMessage

class mailbox.BabylMessage([message])

具有Babyl特定行为的消息。参数消息的含义与Message构造函数相同。

某些消息标签,称为属性,按照惯例定义为具有特殊含义。属性如下:

标签说明
看不见没有阅读,但以前由MUA检测到
删除标记为随后删除
提交复制到另一个文件或邮箱
回答已回复
转发转发
编辑由用户修改
resentResent

默认情况下,Rmail仅显示可见标题。该BabylMessage级,不过,使用原来的头,因为他们都比较齐全。如果需要,可以明确地访问可见标题。

BabylMessage 实例提供以下方法:

get_labels()

返回消息上的标签列表。

set_labels(labels)

将消息上的标签列表设置为标签

add_label(label)

标签添加到邮件标签列表中。

remove_label(label)

从邮件标签列表中删除标签

get_visible()

返回一个Message实例,其头文件是消息的可见头文件,其正文为空。

set_visible(visible)

设置消息可见标题是相同的标题消息可见参数应该是Message实例,email.message.Message实例,字符串或文件类对象(应该在文本模式下打开)。

update_visible()

BabylMessage实例的原始标题被修改时,可见标题不会自动修改为对应。此方法更新可见标题如下:与相应的原始标题的每个可见首部设置为原始标题的值,没有相应的原始标题的每个可见头被除去,和任何的日期回复到CC主题都存在于原始标题中,但不可见标题添加到可见标题中。

当基于BabylMessage实例创建MaildirMessage实例时,会发生以下转换:

结果状态MaildirMessage状态
“看不见”的标签没有S标志
“已删除”标签T标志
“回答”了标签R标志
“转发”标签P标志

当一个BabylMessage是基于一个创建的实例mboxMessageMMDFMessage实例中,状态X-状态标头省略,下面的转换发生:

结果状态mboxMessage或MMDFMessage状态
“看不见”的标签没有R标志
“已删除”标签D标志
“回答”了标签A标志

当基于BabylMessage实例创建MHMessage实例时,会发生以下转换:

结果状态MHMessage状态
“看不见”的标签“看不见的”序列
“回答”了标签“回答”了序列

2.5. MMDFMessage

class mailbox.MMDFMessage([message])

具有MMDF特定行为的消息。参数消息的含义与Message构造函数相同。

与mbox邮箱中的邮件一样,MMDF邮件与发件人地址和交货日期一起存储在以“From”开头的起始行中。同样,指示消息状态的标志通常存储在StatusX-Status标头中。

MMDF消息的常规标志与mbox消息的常规标志相同,如下所示:

标志含义说明
R
以前由MUA检测到
d删除标记为随后删除
F标记标记为重要
一个回答已回复

“R”和“O”标志存储在状态标题中,“D”,“F”和“A”标志存储在X状态标题中。标志和标题通常以提到的顺序出现。

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)

设置由标志指定的标志并取消设置所有其他标志。参数标志应当在零个或多个的每一个的任何顺序串联'R''O''D''F',和'A'

add_flag(flag)

设置标志指定的标志而不更改其他标志。要一次添加多个标志标志可能是一串多于一个字符。

remove_flag(flag)

取消设置标志指定的标志而不更改其他标志。要一次删除多个标志标志可能是一串多于一个字符。

当基于MMDFMessage实例创建MaildirMessage实例时,将根据MaildirMessage实例的交付日期生成“发件人”行,并进行以下转换:

结果状态MaildirMessage状态
R标志S标志
O标志“cur”子目录
D标志T标志
F标志F标志
一只旗R标志

当基于MMDFMessage实例创建MHMessage实例时,会发生以下转换:

结果状态MHMessage状态
R标志和O标志没有“看不见”的序列
O标志“看不见的”序列
F标志“标记”序列
A标志“回答”了序列

当基于MMDFMessage实例创建BabylMessage实例时,会发生以下转换:

结果状态BabylMessage状态
R标志和O标志没有“看不见”的标签
O标志“看不见”的标签
D标志“已删除”标签
A标志“回答”了标签

当基于MMDFMessage实例创建mboxMessage实例时,“From”行被复制,所有标志直接对应:O标志

结果状态mboxMessage状态
R标志R标志
O标志O标志
D标志D标志
F标志F标志
A标志A标志

3.例外

以下异常类在mailbox模块中定义:

exception mailbox.Error

所有其他模块特定例外的基础类。

exception mailbox.NoSuchMailboxError

在希望找到邮箱但未找到邮箱时引发,例如在实例化具有Mailbox不存在的路径(并且创建参数设置为False)的子类时,或打开不存在的文件夹时引发。

exception mailbox.NotEmptyError

当邮箱不是空的,但预计是,例如删除包含邮件的文件夹时引发。

exception mailbox.ExternalClashError

当程序控制范围之外的某些与邮箱相关的情况导致无法继续时,例如无法获取另一个程序已经拥有锁的锁,或者存在唯一生成的文件名时,就会引发此问题。

exception mailbox.FormatError

当文件中的数据无法分析时引发,MH例如实例试图读取损坏的.mh_sequences文件。

4.弃用的类和方法

Deprecated since version 2.6.

较旧版本的mailbox模块不支持邮箱的修改,例如添加或删除邮件,也不提供用于表示特定于格式的邮件属性的类。为了向后兼容,旧的邮箱类仍然可用,但应该优先使用较新的类。Python 3中删除了旧的类。

较旧的邮箱对象仅支持迭代并提供一个公共方法:

oldmailbox.next()

返回邮箱中的下一条消息,使用传递给邮箱对象构造函数的可选工厂参数创建邮箱。默认情况下,这是一个rfc822.Message对象(请参阅rfc822模块)。根据邮箱实现,此对象的fp属性可能是一个真实的文件对象或模拟文件对象的类实例,如果单个文件中包含多个邮件消息,则会处理消息边界等事情。如果没有更多消息可用,此方法返回None

大多数旧邮箱类别的名称与当前邮箱类名称不同,除了Maildir。为此,新Maildir类定义了一个next()方法,其构造函数与其他新邮箱类稍有不同。

名称与其较新对应项名称不同的旧邮箱类别如下所示:

class mailbox.UnixMailbox(fp[, factory])

访问一个经典的Unix风格邮箱,其中所有邮件都包含在一个文件中,并用From(又名From_)行分隔。文件对象fp指向邮箱文件。可选的工厂参数是可调用的,应该创建新的消息对象。工厂通过邮箱对象的方法调用一个参数fpnext()。默认值是rfc822.Message类(请参阅rfc822模块 - 以及下面的注释)。

注意

由于本模块内部实现的原因,您可能希望以二进制模式打开fp对象。这在Windows上尤为重要。

为了获得最大的可移植性,Unix样式邮箱中的消息由任何以字符串开头的行'From '(如果前面紧跟着两个换行符)进行分隔(注意尾随空格)。由于实践中的变化范围很广,因此From_不应考虑线上的其他因素。但是,目前的实施并没有检查领先的两条换行符。这对大多数应用程序来说通常很好。

UnixMailbox类实现的更严格的版本From_线检查,使用正则表达式通常正确匹配From_的分隔符。它认为分隔线由From name time行分隔。为了获得最大的可移植性,请改用PortableUnixMailbox该类。UnixMailbox除了单独的消息仅由From行分隔以外,此类相同。

class mailbox.PortableUnixMailbox(fp[, factory])

一个不太严格的版本UnixMailbox,它只考虑From在分隔邮件的行的开头。From行的“ 名称 时间 ”部分被忽略,以防止在实践中观察到的一些变化。这是有效的,因为邮件中的行首是在'From '邮件处理软件的交货时引用的。

class mailbox.MmdfMailbox(fp[, factory])

访问MMDF样式的邮箱,其中所有邮件都包含在单个文件中,并由包含4个控制字符的行分隔。文件对象fp指向邮箱文件。可选工厂UnixMailbox班级一样。

class mailbox.MHMailbox(dirname[, factory])

访问一个MH邮箱,一个带有数字名称的单独文件中的每条消息的目录。邮箱目录的名称通过dirname传递。工厂UnixMailbox班级一样。

class mailbox.BabylMailbox(fp[, factory])

访问Babyl邮箱,该邮箱与MMDF邮箱类似。在Babyl格式中,每条消息都有两组标题,即原始标题和可见标题。原始标题出现在仅包含'*** EOOH ***'原始结尾标题)的行的前面,并且该EOOH行后面显示可见的标题。符合Babyl的邮件阅读器将只显示可见标题,而BabylMailbox对象将返回仅包含可见标题的邮件。您必须自己解析邮箱文件以获取原始标题。邮件消息以EOOH行开始,并以仅包含一行的结束'\037\014'工厂UnixMailbox班级一样。

如果您希望将旧的邮箱类与email模块(而不是弃用的rfc822模块)一起使用,则可以这样做:

import email import email.Errors import mailbox def msgfactory(fp): try: return email.message_from_file(fp) except email.Errors.MessageParseError: # Don't return None since that will # stop the mailbox iterator return '' mbox = mailbox.UnixMailbox(fp, msgfactory)

或者,如果您知道您的邮箱只包含格式正确的MIME邮件,则可以将其简化为:

import email import mailbox mbox = mailbox.UnixMailbox(fp, email.message_from_file)

5.例子

将邮箱中的所有邮件的主题打印出来似乎很有趣的简单示例:

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