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)
Mailbox
Maildir格式邮箱的子类。参数工厂
是一个可调用的对象,它接受类似文件的消息表示(其行为如同以二进制模式打开)并返回一个自定义表示。如果工厂
是None
,MaildirMessage
则用作默认消息表示。如果创建
是True
,如果它不存在的邮箱已创建
。
这是由于历史原因,出厂
默认rfc822.Message
和目录名
被命名为这样的,而不是路径
。对于Maildir
像其他Mailbox
子类的实例那样行为的实例,请将工厂
设置为None
。
Maildir是一种基于目录的邮箱格式,为qmail邮件传输代理发明,现在已被其他程序广泛支持。Maildir邮箱中的邮件存储在通用目录结构中的单独文件中。这种设计允许Maildir邮箱被多个不相关的程序访问和修改,而不会造成数据损坏,因此不需要文件锁定。
Maildir的邮箱包含三个子目录,分别为:tmp
,new
,和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格式邮箱的子类。参数工厂
是一个可调用的对象,它接受类似文件的消息表示(其行为如同以二进制模式打开)并返回一个自定义表示。如果工厂
是None
,mboxMessage
则用作默认消息表示。如果创建
是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)
Mailbox
MH格式邮箱的子类。参数工厂
是一个可调用的对象,它接受类似文件的消息表示(其行为如同以二进制模式打开)并返回一个自定义表示。如果工厂
是None
,MHMessage
则用作默认消息表示。如果创建
是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)
Mailbox
Babyl格式邮箱的子类。参数工厂
是一个可调用的对象,它接受类似文件的消息表示(其行为如同以二进制模式打开)并返回一个自定义表示。如果工厂
是None
,BabylMessage
则用作默认消息表示。如果创建
是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)
Mailbox
MMDF格式邮箱的子类。参数工厂
是一个可调用的对象,它接受类似文件的消息表示(其行为如同以二进制模式打开)并返回一个自定义表示。如果工厂
是None
,MMDFMessage
则用作默认消息表示。如果创建
是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
模块的一个子类Message
。mailbox.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
子目录中)。
注意
消息通常是从移动new
到cur
后其邮箱被访问,无论是否该消息已被阅读。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
是基于一个创建的实例mboxMessage
或MMDFMessage
实例中,状态
和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实现中该数据的确切格式有很大差异。指示消息状态的标志,例如它是否被读取或标记为重要,通常存储在Status
和X-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消息不支持传统意义上的标记或标志,但它们确实支持序列,它们是任意消息的逻辑分组。某些邮件阅读程序(尽管不是标准的mh
和nmh
)使用序列的方式与标志与其他格式的使用方式大致相同,如下所示:
序列 | 说明 |
---|---|
看不见 | 没有阅读,但以前由MUA检测到 |
回答 | 已回复 |
已标记 | 标记为重要 |
MHMessage
实例提供以下方法:
get_sequences()
返回包含此消息的序列名称列表。
set_sequences(sequences)
设置包含此消息的序列列表。
add_sequence(sequence)
将序列
添加到包含此消息的序列
列表中。
remove_sequence(sequence)
从包含此消息的序列
列表中删除序列
。
当基于MHMessage
实例创建MaildirMessage
实例时,会发生以下转换:
结果状态 | MaildirMessage状态 |
---|---|
“看不见的”序列 | 没有S标志 |
“回答”了序列 | R标志 |
“标记”序列 | F标志 |
当一个MHMessage
是基于一个创建的实例mboxMessage
或MMDFMessage
实例中,状态
和X-状态
标头省略,下面的转换发生:
结果状态 | mboxMessage或MMDFMessage状态 |
---|---|
“看不见的”序列 | 没有R标志 |
“回答”了序列 | A标志 |
“标记”序列 | F标志 |
当基于MHMessage
实例创建BabylMessage
实例时,会发生以下转换:
结果状态 | BabylMessage状态 |
---|---|
“看不见的”序列 | “看不见”的标签 |
“回答”了序列 | “回答”了标签 |
2.4. BabylMessage
class mailbox.BabylMessage([message])
具有Babyl特定行为的消息
。参数消息
的含义与Message
构造函数相同。
某些消息标签,称为属性
,按照惯例定义为具有特殊含义。属性
如下:
标签 | 说明 |
---|---|
看不见 | 没有阅读,但以前由MUA检测到 |
删除 | 标记为随后删除 |
提交 | 复制到另一个文件或邮箱 |
回答 | 已回复 |
转发 | 转发 |
编辑 | 由用户修改 |
resent | Resent |
默认情况下,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
是基于一个创建的实例mboxMessage
或MMDFMessage
实例中,状态
和X-状态
标头省略,下面的转换发生:
结果状态 | mboxMessage或MMDFMessage状态 |
---|---|
“看不见”的标签 | 没有R标志 |
“已删除”标签 | D标志 |
“回答”了标签 | A标志 |
当基于BabylMessage
实例创建MHMessage
实例时,会发生以下转换:
结果状态 | MHMessage状态 |
---|---|
“看不见”的标签 | “看不见的”序列 |
“回答”了标签 | “回答”了序列 |
2.5. MMDFMessage
class mailbox.MMDFMessage([message])
具有MMDF特定行为的消息
。参数消息
的含义与Message
构造函数相同。
与mbox邮箱中的邮件一样,MMDF邮件与发件人地址和交货日期一起存储在以“From”开头的起始行中。同样,指示消息状态的标志通常存储在Status
和X-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
指向邮箱文件。可选的工厂
参数是可调用的,应该创建新的消息对象。工厂
通过邮箱对象的方法调用一个参数fp
next()
。默认值是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()