On this page
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类的方法:
类别
email.message.
Message
- 构造函数不带任何参数。
as_string
([* unixfrom *])- 返回整平为字符串的整个消息。当可选的* unixfrom *为
True
时,信封头包含在返回的字符串中。 * unixfrom *默认为False
。如果需要填写默认值以完成对字符串的转换(例如,可能会生成或修改 MIME 边界),则拼合消息可能会触发对Message的更改。
- 返回整平为字符串的整个消息。当可选的* unixfrom *为
请注意,此方法是为方便起见而提供的,不一定总是按照您想要的方式格式化消息。例如,默认情况下,它会粉碎以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()
__str__
( )- 等效于
as_string(unixfrom=True)
。
- 等效于
is_multipart
( )- 如果消息的有效负载是子Message对象的列表,则返回
True
,否则返回False
。当is_multipart()返回False
时,有效负载应为字符串对象。
- 如果消息的有效负载是子Message对象的列表,则返回
set_unixfrom
(* unixfrom *)- 将邮件的信封 Headers 设置为* unixfrom *,它应该是一个字符串。
get_unixfrom
( )- 返回邮件的信封头。如果从未设置信封头,则默认为
None
。
- 返回邮件的信封头。如果从未设置信封头,则默认为
attach
(有效负载)- 将给定的* payload *添加到当前有效负载中,该有效负载必须为
None
或调用之前的Message对象列表。调用之后,有效负载将始终是Message个对象的列表。如果要将有效负载设置为标量对象(例如字符串),请改用set_payload()。
- 将给定的* payload *添加到当前有效负载中,该有效负载必须为
get_payload
([* i * [,* decode *]])- 返回当前有效负载,当is_multipart()为
True
时将为Message对象的列表,或当is_multipart()为False
时为字符串。如果有效负载是列表,并且您对列表对象进行了突变,则可以在适当位置修改消息的有效负载。
- 返回当前有效负载,当is_multipart()为
使用可选参数* i ,如果is_multipart()是True
,则get_payload()将返回有效载荷的第 i 个元素,从零开始计数。如果 i 小于 0 或大于或等于有效载荷中的项目数,则将引发IndexError。如果有效载荷是字符串(即is_multipart()为False
)并且给出了 i *,则引发TypeError。
可选的* decode 是根据 Content-Transfer-Encoding Headers 指示是否应解码有效载荷的标志。当True
并且消息不是 Multipart 时,如果此 Headers 的值为quoted-printable
或base64
,则将对有效负载进行解码。如果使用其他某种编码,或者缺少 Content-Transfer-Encoding Headers,或者有效负载包含伪造的 base64 数据,则有效负载将按原样返回(未编码)。如果消息是 Multipart 消息,并且 decode *标志是True
,则返回None
。 * decode *的默认值为False
。
set_payload
(有效负载 [,字符集])- 将整个消息对象的有效负载设置为* payload 。确保有效载荷不变是 Client 的责任。可选的 charset *设置消息的默认字符集;有关详情,请参见set_charset()。
在版本 2.2.2 中更改:添加了* charset *参数。
set_charset
(字符集)- 将有效负载的字符集设置为* charset ,它可以是Charset实例(请参见email.charset),命名字符集的字符串或
None
。如果是字符串,它将被转换为Charset实例。如果 charset 为None
,则charset
参数将从 Content-Type *Headers 中删除(该消息将不会进行其他修改)。其他任何东西都会生成TypeError。
- 将有效负载的字符集设置为* charset ,它可以是Charset实例(请参见email.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。
get_charset
( )- 返回与消息的有效负载关联的Charset实例。
版本 2.2.2 中的新Function。
下列方法实现了一个类似于 Map 的接口,用于访问消息的 RFC 2822Headers。请注意,这些方法与常规 Map(即字典)接口之间在语义上有所不同。例如,在词典中没有重复的键,但是这里可能有重复的消息头。同样,在字典中并没有保证keys()返回的键的 Sequences,但是在Message对象中,Headers 总是按照它们在原始消息中出现的 Sequences 返回,或者在以后添加到消息中。删除然后重新添加的任何 Headers 始终附加在 Headers 列表的末尾。
这些语义上的差异是故意的,并且倾向于最大的便利性。
请注意,在所有情况下,消息中存在的任何信封头都不会包含在 Map 接口中。
__len__
( )- 返回标题总数,包括重复项。
__contains__
(* name *)- 如果消息对象具有一个名为* name 的字段,则返回 true。匹配不区分大小写,并且 name *不应包含结尾的冒号。用于
in
运算符,例如:
- 如果消息对象具有一个名为* name 的字段,则返回 true。匹配不区分大小写,并且 name *不应包含结尾的冒号。用于
if 'message-id' in myMessage:
print 'Message-ID:', myMessage['message-id']
__getitem__
(* name *)- 返回命名标题字段的值。 * name *不应包含冒号分隔符。如果缺少标题,则返回
None
;否则,返回_。永远不会提出KeyError。
- 返回命名标题字段的值。 * name *不应包含冒号分隔符。如果缺少标题,则返回
请注意,如果命名字段在消息的标题中多次出现,则将不确定返回哪个字段值。使用get_all()方法获取所有现存命名报头的值。
__setitem__
(* name , val *)- 向消息添加 Headers,其字段名称为* name ,值为 val *。该字段将附加到邮件现有字段的末尾。
请注意,这不会覆盖或删除任何具有相同名称的现有 Headers。如果要确保新标题是消息中字段名称为* name *的唯一字段,请首先删除该字段,例如:
del msg['subject']
msg['subject'] = 'Python roolz!'
__delitem__
(* name *)- 从邮件标题中删除所有出现的名称为* name *的字段。如果标题字段中不存在命名字段,则不会引发异常。
has_key
(* name *)- 如果消息包含名为* name *的头字段,则返回 true,否则返回 false。
keys
( )- 返回所有消息标题字段名称的列表。
values
( )- 返回所有消息字段值的列表。
items
( )- 返回一个包含所有消息字段标题和值的 2Tuples 列表。
get
(* name * [,* failobj *])- 返回命名标题字段的值。这与getitem()相同,除了如果缺少指定的 Headers(默认为
None
),则返回可选的* failobj *。
- 返回命名标题字段的值。这与getitem()相同,除了如果缺少指定的 Headers(默认为
以下是一些其他有用的方法:
get_all
(* name * [,* failobj *])- 返回名为* name 的字段的所有值的列表。如果消息中没有这样的命名头,则返回 failobj *(默认为
None
)。
- 返回名为* name 的字段的所有值的列表。如果消息中没有这样的命名头,则返回 failobj *(默认为
add_header
(* _name , _value ,** _ params *)- 扩展头设置。此方法与setitem()相似,不同之处在于可以提供其他 Headers 参数作为关键字参数。 * _name 是要添加的标题字段, _ value 是标题的 primary *值。
对于关键字参数字典* _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"
replace_header
(* _name , _value *)- 替换标题。替换在与* _name *匹配的消息中找到的第一个 Headers,并保留 HeadersSequences 和字段名大小写。如果找不到匹配的 Headers,则引发KeyError。
版本 2.2.2 中的新Function。
get_content_type
( )- 返回消息的 Content Type。返回的字符串被强制转换为小写形式* maintype/subtype 。如果消息中没有 Content-Type *Headers,则将返回get_default_type()给出的默认类型。由于根据 RFC 2045,消息始终具有默认类型,因此get_content_type()将始终返回值。
RFC 2045将消息的默认类型定义为* text/plain ,除非它出现在 multipart/digest 容器内,在这种情况下它将是 message/rfc822 。如果 Content-Type Headers 具有无效的类型规范,则 RFC 2045要求默认类型为 text/plain *。
版本 2.2.2 中的新Function。
get_content_maintype
( )- 返回消息的主要 Content Type。这是get_content_type()返回的字符串的* maintype *部分。
版本 2.2.2 中的新Function。
get_content_subtype
( )- 返回消息的子 Content Type。这是get_content_type()返回的字符串的* subtype *部分。
版本 2.2.2 中的新Function。
get_default_type
( )- 返回默认的 Content Type。大多数消息的默认 Content Type 为* text/plain ,但作为 multipart/digest 容器的子部分的消息除外。这些子部分的默认 Content Type 为 message/rfc822 *。
版本 2.2.2 中的新Function。
set_default_type
(* ctype *)- 设置默认的 Content Type。 * ctype 应该是 text/plain 或 message/rfc822 ,尽管这不是强制性的。默认 Content Type 未存储在 Content-Type *Headers 中。
版本 2.2.2 中的新Function。
get_params
([* failobj * [,* header * [,* unquote *]]])- 以列表形式返回消息的* Content-Type 参数。返回列表的元素是键/值对的 2Tuples,在
'='
符号上拆分。'='
的左侧是键,而右侧是值。如果参数中没有'='
符号,则该值为空字符串,否则该值如get_param()中所述,并且如果可选的 unquote *为True
(默认值),则该值不加引号。
- 以列表形式返回消息的* Content-Type 参数。返回列表的元素是键/值对的 2Tuples,在
可选的* failobj 是没有 Content-Type 头时要返回的对象。可选的 header 是要搜索的标题,而不是 Content-Type *。
在版本 2.2.2 中更改:添加了* unquote *参数。
get_param
(* param * [,* failobj * [,* header * [,* unquote *]]])- 以字符串形式返回* Content-Type Headers 参数 param 的值。如果消息没有 Content-Type 头,或者没有这样的参数,则返回 failobj *(默认为
None
)。
- 以字符串形式返回* Content-Type Headers 参数 param 的值。如果消息没有 Content-Type 头,或者没有这样的参数,则返回 failobj *(默认为
如果提供了可选的* header ,则指定要使用的消息头,而不是 Content-Type *。
参数键始终不区分大小写地进行比较。返回值可以是字符串,也可以是 3Tuples(如果参数是 RFC 2231编码)。当它是一个三 Tuples 时,该值的元素的格式为(CHARSET, LANGUAGE, VALUE)
。请注意CHARSET
和LANGUAGE
都可以是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 的返回值。
set_param
((* param , value * [,* header * [,* requote * [,* charset * [,* language *]]]])- 在* Content-Type Headers 中设置一个参数。如果参数已存在于标题中,则其值将替换为 value 。如果尚未为该消息定义 Content-Type Headers,则将其设置为 text/plain *,并将按照 RFC 2045附加新的参数值。
可选的* header 指定 Content-Type 的备用标题,除非可选的 requote *为False
(默认为True
),否则所有参数都将被引用。
如果指定了可选的* charset ,则该参数将根据 RFC 2231进行编码。可选的 language *指定 RFC 2231 语言,默认为空字符串。 * charset 和 language *都应为字符串。
版本 2.2.2 中的新Function。
del_param
(* param * [,* header * [,* requote *]])- 从* Content-Type Headers 中完全删除给定的参数。Headers 将在没有参数或其值的情况下被重写。除非 requote 为
False
(默认值为True
),否则所有值都将根据需要加上引号。可选的 header 指定 Content-Type *的替代形式。
- 从* Content-Type Headers 中完全删除给定的参数。Headers 将在没有参数或其值的情况下被重写。除非 requote 为
版本 2.2.2 中的新Function。
set_type
(* type [,Headers] [,重新引用] *)- 设置* Content-Type *Headers 的主要类型和子类型。 * type 必须是形式为 maintype/subtype *的字符串,否则引发ValueError。
此方法替换* Content-Type Headers,将所有参数保留在适当的位置。如果 requote *为False
,则保留现有 Headers 的引用不变,否则参数将被引用(默认)。
可以在* header 参数中指定备用标题。设置 Content-Type Headers 后,还将添加 MIME-Version *Headers。
版本 2.2.2 中的新Function。
get_filename
([* failobj *])- 返回消息的* Content-Disposition Headers 的
filename
参数的值。如果标题没有filename
参数,则此方法将退回到在 Content-Type 标题上寻找name
参数。如果两者均未找到,或者标题丢失,则返回 failobj *。返回的字符串将始终按照email.utils.unquote()取消引用。
- 返回消息的* Content-Disposition Headers 的
get_boundary
([* failobj *])- 返回消息的* Content-Type Headers 的
boundary
参数的值,如果 Headers 丢失或没有boundary
参数,则返回 failobj *。返回的字符串将始终按照email.utils.unquote()取消引用。
- 返回消息的* Content-Type Headers 的
set_boundary
(* boundary *)- 将* Content-Type Headers 的
boundary
参数设置为 boundary 。如有必要,set_boundary()将始终引用 boundary 。如果消息对象没有 Content-Type *Headers,则引发HeaderParseError。
- 将* Content-Type Headers 的
请注意,使用此方法与passadd_header()删除旧的* Content-Type Headers 并添加具有新边界的新方法有一点不同,因为set_boundary()保留了 Content-Type *Headers 在 Headers 列表中的 Sequences。但是,它不会保留原始的 Content-TypeHeaders 中可能存在的任何连续行。
get_content_charset
([* failobj *])- 返回* Content-Type Headers 的
charset
参数(强制小写)。如果没有 Content-Type 头,或者该头没有charset
参数,则返回 failobj *。
- 返回* Content-Type Headers 的
请注意,此方法不同于get_charset(),后者返回Charset实例以获取消息正文的默认编码。
版本 2.2.2 中的新Function。
get_charsets
([* failobj *])- 返回包含消息中字符集名称的列表。如果消息是* multipart *,则列表将为有效负载中的每个子部分包含一个元素,否则,它将为长度为 1 的列表。
列表中的每个项目都是一个字符串,它是表示子部分的* Content-Type 标题中charset
参数的值。但是,如果子部分没有 Content-Type Headers,没有charset
参数或者不是 text 主 MIME 类型,则返回列表中的该项将是 failobj *。
walk
( )
这是一个打印 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
- MIME 文档的格式允许在标题后的空白行和第一个 Multipart 边界字符串之间添加一些文本。通常,此文本在支持 MIME 的邮件阅读器中永远不可见,因为它不在标准 MIME 防护范围内。但是,在查看邮件的原始文本时,或在不支持 MIME 的阅读器中查看邮件时,此文本可能会变得可见。
- preamble 属性包含 MIME 文档的前导多余的装甲文本。当Parser在标题之后但在第一个边界字符串之前发现一些文本时,它将将此文本分配给消息的 preamble 属性。当Generator写出 MIME 消息的纯文本表示形式时,如果发现该消息具有 preamble *属性,它将在 Headers 和第一个边界之间的区域中写入此文本。有关详细信息,请参见email.parser和email.generator。
请注意,如果消息对象没有前导,则* preamble *属性将为None
。
epilogue
-
- epilogue 属性的作用方式与 preamble *属性相同,不同之处在于它包含出现在消息的最后边界和末尾之间的文本。
-
在版本 2.5 中进行了更改:您无需将结尾部分设置为空字符串,即可使Generator在文件末尾打印换行符。
defects
-
- defects *属性包含解析此消息时发现的所有问题的列表。有关可能的解析缺陷的详细说明,请参见email.errors。
-
2.4 版的新Function。