18.1.1. email.message:代表电子邮件

email包中的中心类是Message类,从email.message模块导入。它是email对象模型的 Base Class。 Message提供了用于设置和查询头字段以及访问消息正文的核心Function。

从概念上讲,Message对象由* headers payloads *组成。Headers 是 RFC 2822样式的字段名称和值,其中字段名称和值之间用冒号分隔。冒号既不是字段名也不是字段值的一部分。

Headers 以保留大小写的形式存储和返回,但不区分大小写。也可能只有一个信封 Headers,也称为* Unix-From Headers 或From_Headers。对于简单的邮件对象,有效负载可以是字符串,也可以是 MIME 容器文档的Message对象列表(例如 multipart/* message/rfc822 *)。

Message对象提供用于访问消息头的 Map 样式接口,以及用于访问头和有效负载的显式接口。它提供了方便的方法来生成消息对象树的纯文本表示形式,访问常用的头参数以及递归遍历对象树。

以下是Message类的方法:

请注意,此方法是为方便起见而提供的,不一定总是按照您想要的方式格式化消息。例如,默认情况下,它会粉碎以From开头的行。为了获得更大的灵 Active,请实例化一个Generator实例并直接使用其flatten()方法。例如:

from cStringIO import StringIO
from email.generator import Generator
fp = StringIO()
g = Generator(fp, mangle_from_=False, maxheaderlen=60)
g.flatten(msg)
text = fp.getvalue()

使用可选参数* i ,如果is_multipart()True,则get_payload()将返回有效载荷的第 i 个元素,从零开始计数。如果 i 小于 0 或大于或等于有效载荷中的项目数,则将引发IndexError。如果有效载荷是字符串(即is_multipart()False)并且给出了 i *,则引发TypeError

可选的* decode 是根据 Content-Transfer-Encoding Headers 指示是否应解码有效载荷的标志。当True并且消息不是 Multipart 时,如果此 Headers 的值为quoted-printablebase64,则将对有效负载进行解码。如果使用其他某种编码,或者缺少 Content-Transfer-Encoding Headers,或者有效负载包含伪造的 base64 数据,则有效负载将按原样返回(未编码)。如果消息是 Multipart 消息,并且 decode *标志是True,则返回None。 * decode *的默认值为False

在版本 2.2.2 中更改:添加了* charset *参数。

如果不存在* MIME-Version Headers,则将添加一个。如果不存在 Content-Type Headers,则会添加一个 text/plain 值。无论 Content-Type Headers 已经存在,其charset参数都将设置为 charset.output_charset 。如果 charset.input_charset charset.output_charset 不同,则有效负载将重新编码为 output_charset 。如果不存在 Content-Transfer-Encoding Headers,则有效载荷将根据需要使用指定的Charset进行传输编码,并添加具有适当值的 Headers。如果 Content-Transfer-Encoding Headers 已经存在,则假定已经使用该 Content-Transfer-Encoding *对有效负载进行了正确编码,并且未对其进行修改。

该消息将被假定为* text/*类型,其有效负载采用 unicode 或 charset.input_charset 编码。在生成消息的纯文本表示形式时,它将被编码或转换为 charset.output_charset 并进行适当的传输编码。 MIMEHeaders( MIME-Version Content-Type Content-Transfer-Encoding *)将根据需要添加。

版本 2.2.2 中的新Function。

版本 2.2.2 中的新Function。

下列方法实现了一个类似于 Map 的接口,用于访问消息的 RFC 2822Headers。请注意,这些方法与常规 Map(即字典)接口之间在语义上有所不同。例如,在词典中没有重复的键,但是这里可能有重复的消息头。同样,在字典中并没有保证keys()返回的键的 Sequences,但是在Message对象中,Headers 总是按照它们在原始消息中出现的 Sequences 返回,或者在以后添加到消息中。删除然后重新添加的任何 Headers 始终附加在 Headers 列表的末尾。

这些语义上的差异是故意的,并且倾向于最大的便利性。

请注意,在所有情况下,消息中存在的任何信封头都不会包含在 Map 接口中。

if 'message-id' in myMessage:
    print 'Message-ID:', myMessage['message-id']

请注意,如果命名字段在消息的标题中多次出现,则将不确定返回哪个字段值。使用get_all()方法获取所有现存命名报头的值。

请注意,这不会覆盖或删除任何具有相同名称的现有 Headers。如果要确保新标题是消息中字段名称为* name *的唯一字段,请首先删除该字段,例如:

del msg['subject']
msg['subject'] = 'Python roolz!'

以下是一些其他有用的方法:

对于关键字参数字典* _params *中的每个项目,都将键作为参数名称,并将下划线转换为破折号(因为破折号在 Python 标识符中是非法的)。通常,除非值是None,否则参数将作为key="value"添加,在这种情况下,仅会添加键。如果值包含非 ASCII 字符,则必须以(CHARSET, LANGUAGE, VALUE)格式将其指定为三个 Tuples,其中CHARSET是一个字符串,用于命名用于对值进行编码的字符集,通常LANGUAGE可以设置为None或空字符串(请参见 RFC 2231(其他可能性),而VALUE是包含非 ASCII 代码点的字符串值。

这是一个例子:

msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')

这将添加一个看起来像

Content-Disposition: attachment; filename="bud.gif"

具有非 ASCII 字符的示例:

msg.add_header('Content-Disposition', 'attachment',
               filename=('iso-8859-1', '', 'Fußballer.ppt'))

Which produces

Content-Disposition: attachment; filename*="iso-8859-1''Fu%DFballer.ppt"

版本 2.2.2 中的新Function。

RFC 2045将消息的默认类型定义为* text/plain ,除非它出现在 multipart/digest 容器内,在这种情况下它将是 message/rfc822 。如果 Content-Type Headers 具有无效的类型规范,则 RFC 2045要求默认类型为 text/plain *。

版本 2.2.2 中的新Function。

版本 2.2.2 中的新Function。

版本 2.2.2 中的新Function。

版本 2.2.2 中的新Function。

版本 2.2.2 中的新Function。

可选的* failobj 是没有 Content-Type 头时要返回的对象。可选的 header 是要搜索的标题,而不是 Content-Type *。

在版本 2.2.2 中更改:添加了* unquote *参数。

如果提供了可选的* header ,则指定要使用的消息头,而不是 Content-Type *。

参数键始终不区分大小写地进行比较。返回值可以是字符串,也可以是 3Tuples(如果参数是 RFC 2231编码)。当它是一个三 Tuples 时,该值的元素的格式为(CHARSET, LANGUAGE, VALUE)。请注意CHARSETLANGUAGE都可以是None,在这种情况下,您应该考虑将VALUE编码为us-ascii字符集。您通常可以忽略LANGUAGE

如果您的应用程序不关心参数是否按照 RFC 2231进行编码,则可以pass调用email.utils.collapse_rfc2231_value()并从get_param()传入返回值来折叠参数值。当该值是一个 Tuples 时,它将返回经过适当解码的 Unicode 字符串;如果不是,则返回未引用的原始字符串。例如:

rawparam = msg.get_param('foo')
param = email.utils.collapse_rfc2231_value(rawparam)

在任何情况下,除非* unquote *设置为False,否则参数值(返回的字符串或三 Tuples 中的VALUE项)始终不加引号。

在版本 2.2.2 中进行了更改:添加了* unquote *参数,并且可能有 3Tuples 的返回值。

可选的* header 指定 Content-Type 的备用标题,除非可选的 requote *为False(默认为True),否则所有参数都将被引用。

如果指定了可选的* charset ,则该参数将根据 RFC 2231进行编码。可选的 language *指定 RFC 2231 语言,默认为空字符串。 * charset language *都应为字符串。

版本 2.2.2 中的新Function。

版本 2.2.2 中的新Function。

此方法替换* Content-Type Headers,将所有参数保留在适当的位置。如果 requote *为False,则保留现有 Headers 的引用不变,否则参数将被引用(默认)。

可以在* header 参数中指定备用标题。设置 Content-Type Headers 后,还将添加 MIME-Version *Headers。

版本 2.2.2 中的新Function。

请注意,使用此方法与passadd_header()删除旧的* Content-Type Headers 并添加具有新边界的新方法有一点不同,因为set_boundary()保留了 Content-Type *Headers 在 Headers 列表中的 Sequences。但是,它不会保留原始的 Content-TypeHeaders 中可能存在的任何连续行。

请注意,此方法不同于get_charset(),后者返回Charset实例以获取消息正文的默认编码。

版本 2.2.2 中的新Function。

列表中的每个项目都是一个字符串,它是表示子部分的* Content-Type 标题中charset参数的值。但是,如果子部分没有 Content-Type Headers,没有charset参数或者不是 text 主 MIME 类型,则返回列表中的该项将是 failobj *。

这是一个打印 Multipart 消息结构的每个部分的 MIME 类型的示例:

>>> for part in msg.walk():
...     print part.get_content_type()
multipart/report
text/plain
message/delivery-status
text/plain
text/plain
message/rfc822

在版本 2.5 中进行了更改:先前弃用的方法get_type()get_main_type()get_subtype()已删除。

Message对象还可以选择包含两个实例属性,可以在生成 MIME 消息的纯文本时使用它们。

请注意,如果消息对象没有前导,则* preamble *属性将为None

在版本 2.5 中进行了更改:您无需将结尾部分设置为空字符串,即可使Generator在文件末尾打印换行符。

2.4 版的新Function。

首页