18.1.1. email.message:表示电子邮件消息 — Python 文档

来自菜鸟教程
Python/docs/2.7/library/email.message
跳转至:导航、​搜索

18.1.1. 电子邮件 :表示电子邮件

email 包中的中心类是 Message 类,从 email.message 模块导入。 它是 email 对象模型的基类。 Message 提供设置和查询头域以及访问消息体的核心功能。

从概念上讲,Message 对象由 headerspayloads 组成。 标头是 RFC 2822 样式的字段名称和值,其中字段名称和值由冒号分隔。 冒号不是字段名称或字段值的一部分。

标头以保留大小写的形式存储和返回,但不区分大小写匹配。 也可能有一个信封头,也称为 Unix-From 头或 From_ 头。 在简单消息对象的情况下,有效负载是一个字符串,或者是 MIME 容器文档的 Message 对象列表(例如 multipart/*message/rfc822)。

Message 对象提供了一个用于访问消息头的映射样式接口,以及一个用于访问头和有效负载的显式接口。 它为生成消息对象树的平面文本表示、访问常用头参数以及递归遍历对象树提供了方便的方法。

以下是 Message 类的方法:

class email.message.Message

构造函数不接受任何参数。

as_string([unixfrom])

以字符串形式返回整条消息。 当可选的 unixfromTrue 时,信封头包含在返回的字符串中。 unixfrom 默认为 False。 如果需要填充默认值以完成到字符串的转换(例如,可能会生成或修改 MIME 边界),则扁平化消息可能会触发对 Message 的更改。

请注意,此方法是为了方便而提供的,可能并不总是按照您想要的方式格式化消息。 例如,默认情况下,它会破坏以 From 开头的行。 为了获得更大的灵活性,请实例化 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()
__str__()

相当于 as_string(unixfrom=True)

is_multipart()

如果消息的有效负载是子 Message 对象的列表,则返回 True,否则返回 False。 当 is_multipart() 返回 False 时,payload 应该是一个字符串对象。

set_unixfrom(unixfrom)

将消息的信封头设置为 unixfrom,它应该是一个字符串。

get_unixfrom()

返回消息的信封头。 如果从未设置信封头,则默认为 None

attach(payload)

将给定的 payload 添加到当前有效负载中,该负载必须是 None 或调用前的 Message 对象列表。 调用后,有效负载将始终是 Message 对象的列表。 如果要将有效负载设置为标量对象(例如 字符串),请改用 set_payload()

get_payload([i[, decode]])

返回当前的payload,当is_multipart()True时为Message对象列表,is_multipart()时为字符串是 False。 如果有效负载是一个列表并且您改变了列表对象,则您就地修改了消息的有效负载。

使用可选参数 iget_payload() 将返回有效载荷的第 i 个元素,从零开始计数,如果 is_multipart() ] 是 True。 如果 i 小于 0 或大于或等于有效负载中的项目数,则会引发 IndexError。 如果有效载荷是一个字符串(即 is_multipart()False) 并给出 iTypeError 被提高。

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

set_payload(payload[, charset])

将整个消息对象的有效负载设置为 payload。 确保有效载荷不变是客户的责任。 可选 charset 设置消息的默认字符集; 有关详细信息,请参阅 set_charset()

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

set_charset(charset)

将有效负载的字符集设置为 charset,它可以是 Charset 实例(请参阅 email.charset)、命名字符集的字符串,或None。 如果是字符串,则会转换为 Charset 实例。 如果 charsetNone,则 charset 参数将从 Content-Type 标头中删除(消息不会被另外修改)。 其他任何东西都会生成 TypeError

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

消息将被假定为 text/* 类型,有效载荷为 unicode 或使用 charset.input_charset 编码。 在生成消息的纯文本表示时,如果需要,它将被编码或转换为 charset.output_charset 并正确传输编码。 MIME 标头(MIME-VersionContent-TypeContent-Transfer-Encoding)将根据需要添加。

2.2.2 版中的新功能。

get_charset()

返回与消息有效负载关联的 Charset 实例。

2.2.2 版中的新功能。

以下方法实现了一个类似于映射的接口,用于访问消息的 RFC 2822 标头。 请注意,这些方法和法线映射之间存在一些语义差异(即 字典)界面。 例如,在字典中没有重复的键,但这里可能有重复的消息头。 此外,在字典中,keys() 返回的键的顺序没有保证,但在 Message 对象中,标题总是按照它们在原始消息中出现的顺序返回,或稍后添加到消息中。 任何删除然后重新添加的标题总是附加到标题列表的末尾。

这些语义差异是有意的,偏向于最大程度的便利。

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

__len__()

返回标题的总数,包括重复项。

__contains__(name)

如果消息对象具有名为 name 的字段,则返回 true。 匹配不区分大小写,并且 name 不应包含尾随冒号。 用于 in 运算符,例如:

if 'message-id' in myMessage:
    print 'Message-ID:', myMessage['message-id']
__getitem__(name)

返回命名头字段的值。 name 不应包含冒号字段分隔符。 如果缺少header,则返回NoneKeyError 永远不会被提升。

请注意,如果命名字段在消息的标题中出现多次,那么将返回这些字段值中的哪一个是未定义的。 使用 get_all() 方法获取所有现存命名头的值。

__setitem__(name, val)

使用字段名称 name 和值 val 向消息添加标题。 该字段附加到消息现有字段的末尾。

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

del msg['subject']
msg['subject'] = 'Python roolz!'
__delitem__(name)

从消息的标题中删除所有出现的名称为 name 的字段。 如果标题中不存在命名字段,则不会引发异常。

has_key(name)

如果消息包含名为 name 的头字段,则返回 true,否则返回 false。

keys()

返回所有消息的标题字段名称的列表。

values()

返回所有消息字段值的列表。

items()

返回包含所有消息的字段标题和值的 2 元组列表。

get(name[, failobj])

返回命名头字段的值。 这与 __getitem__() 相同,除了可选的 failobj 在指定的头文件丢失时返回(默认为 None)。

以下是一些额外的有用方法:

get_all(name[, failobj])

返回名为 name 的字段的所有值的列表。 如果消息中没有这样的命名头,则返回 failobj(默认为 None)。

add_header(_name, _value, **_params)

扩展标题设置。 此方法类似于 __setitem__() 不同之处在于可以提供额外的标头参数作为关键字参数。 _name 是要添加的标头字段,_value 是标头的 primary 值。

对于关键字参数字典 _params 中的每一项,键作为参数名称,下划线转换为破折号(因为破折号在 Python 标识符中是非法的)。 通常情况下,参数会被添加为key="value",除非值为None,在这种情况下,只会添加键。 如果值包含非 ASCII 字符,则必须以 (CHARSET, LANGUAGE, VALUE) 格式将其指定为三元组,其中 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'))

其中产生

Content-Disposition: attachment; filename*="iso-8859-1''Fu%DFballer.ppt"
replace_header(_name, _value)

替换标题。 替换在消息中找到的与 _name 匹配的第一个标头,保留标头顺序和字段名称大小写。 如果未找到匹配的标头,则会引发 KeyError

2.2.2 版中的新功能。

get_content_type()

返回消息的内容类型。 返回的字符串被强制转换为 maintype/subtype 形式的小写。 如果消息中没有 Content-Type 标头,则将返回 get_default_type() 给出的默认类型。 由于根据 RFC 2045,消息总是有一个默认类型,get_content_type() 将总是返回一个值。

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

2.2.2 版中的新功能。

get_content_maintype()

返回消息的主要内容类型。 这是 get_content_type() 返回的字符串的 maintype 部分。

2.2.2 版中的新功能。

get_content_subtype()

返回消息的子内容类型。 这是 get_content_type() 返回的字符串的 subtype 部分。

2.2.2 版中的新功能。

get_default_type()

返回默认内容类型。 大多数消息的默认内容类型为 text/plain,但属于 multipart/digest 容器子部分的消息除外。 此类子部分的默认内容类型为 message/rfc822

2.2.2 版中的新功能。

set_default_type(ctype)

设置默认内容类型。 ctype 应该是 text/plainmessage/rfc822,尽管这不是强制执行的。 默认内容类型不存储在 Content-Type 标头中。

2.2.2 版中的新功能。

get_params([failobj[, header[, unquote]]])

以列表形式返回消息的 Content-Type 参数。 返回列表的元素是键/值对的 2 元组,在 '=' 符号上拆分。 '='的左边是键,右边是值。 如果参数中没有 '=' 符号,则值为空字符串,否则该值如 get_param() 中所述,如果可选 unquote 是不加引号的True(默认)。

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

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

get_param(param[, failobj[, header[, unquote]]])

以字符串形式返回 Content-Type 标头参数 param 的值。 如果消息没有 Content-Type 头或没有这样的参数,则返回 failobj(默认为 None)。

可选的 header 如果给定,则指定要使用的消息头而不是 Content-Type

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

如果您的应用程序不关心参数是否按照 RFC 2231 进行编码,您可以通过调用 email.utils.collapse_rfc2231_value() 折叠参数值, 传入来自 get_param() 的返回值。 当值是元组时,这将返回一个适当解码的 Unicode 字符串,如果不是,则返回不带引号的原始字符串。 例如:

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

在任何情况下,参数值(返回的字符串或 3 元组中的 VALUE 项)总是不带引号的,除非 unquote 设置为 False

在 2.2.2 版更改:添加了 unquote 参数,并且可以使用 3 元组返回值。

set_param(param, value[, header[, requote[, charset[, language]]]])

Content-Type 标头中设置参数。 如果该参数已存在于头文件中,则其值将替换为 value。 如果尚未为此消息定义 Content-Type 标头,则将其设置为 text/plain 并且将按照 附加新参数值]RFC 2045

可选的 header 指定了 Content-Type 的替代标头,所有参数将根据需要被引用,除非可选的 requoteFalse(默认)是 True)。

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

2.2.2 版中的新功能。

del_param(param[, header[, requote]])

Content-Type 标头中完全删除给定的参数。 标头将在没有参数或其值的情况下重写。 除非 requoteFalse(默认值为 True),则所有值都将根据需要引用。 可选的 header 指定了 Content-Type 的替代。

2.2.2 版中的新功能。

set_type(type[, header][, requote])

设置 Content-Type 标头的主要类型和子类型。 type 必须是 maintype/subtype 形式的字符串,否则会引发 ValueError

此方法替换 Content-Type 标头,保留所有参数。 如果 requoteFalse,这将保留现有标题的引用,否则参数将被引用(默认)。

可以在 header 参数中指定替代标头。 当设置 Content-Type 标头时,还会添加 MIME-Version 标头。

2.2.2 版中的新功能。

get_filename([failobj])

返回消息的 Content-Disposition 标头的 filename 参数的值。 如果标头没有 filename 参数,则此方法回退到在 Content-Type 标头上查找 name 参数。 如果两者都没有找到,或者头文件丢失,则返回 failobj。 根据 email.utils.unquote(),返回的字符串将始终不加引号。

get_boundary([failobj])

返回消息的 Content-Type 标头的 boundary 参数的值,如果标头丢失或没有 [,则返回 failobj X163X] 参数。 根据 email.utils.unquote(),返回的字符串将始终不加引号。

set_boundary(boundary)

Content-Type 标头的 boundary 参数设置为 boundary。 如有必要,set_boundary() 将始终引用 boundary。 如果消息对象没有 Content-Type 标头,则会引发 HeaderParseError

请注意,使用此方法与删除旧的 Content-Type 标头并通过 add_header() 添加具有新边界的新标头略有不同,因为 set_boundary()[ X195X] 保留 Content-Type 标头在标头列表中的顺序。 但是,它确实 not 保留了原始 Content-Type 标头中可能存在的任何连续行。

get_content_charset([failobj])

返回 Content-Type 标头的 charset 参数,强制为小写。 如果没有 Content-Type 标头,或者该标头没有 charset 参数,则返回 failobj

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

2.2.2 版中的新功能。

get_charsets([failobj])

返回包含消息中字符集名称的列表。 如果消息是 multipart,则列表将包含有效载荷中每个子部分的一个元素,否则,它将是一个长度为 1 的列表。

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

walk()

walk() 方法是一个通用生成器,可用于以深度优先遍历顺序迭代消息对象树的所有部分和子部分。 您通常会使用 walk() 作为 for 循环中的迭代器; 每次迭代返回下一个子部分。

这是一个打印多部分消息结构每个部分的 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

MIME 文档的格式允许在标题后面的空行和第一个多部分边界字符串之间存在一些文本。 通常,此文本在支持 MIME 的邮件阅读器中永远不可见,因为它超出了标准 MIME 范围。 但是,在查看邮件的原始文本时,或在不支持 MIME 的阅读器中查看邮件时,此文本可能会变得可见。

preamble 属性包含此 MIME 文档的前导额外装甲文本。 当 Parser 在头之后但在第一个边界字符串之前发现一些文本时,它会将此文本分配给消息的 preamble 属性。 当 Generator 写出一个 MIME 消息的纯文本表示时,它发现该消息有一个 preamble 属性,它会在头部和头部之间的区域写入该文本第一个边界。 有关详细信息,请参阅 email.parseremail.generator

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

epilogue

epilogue 属性的作用与 preamble 属性相同,不同之处在于它包含出现在消息最后边界和结尾之间的文本。

2.5 版更改: 无需将结尾设置为空字符串,以便 Generator 在文件末尾打印换行符。

defects

defects 属性包含解析此消息时发现的所有问题的列表。 有关可能的解析缺陷的详细说明,请参阅 email.errors

2.4 版中的新功能。