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

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

email.message:表示电子邮件

源代码: :source:`Lib/email/message.py`



3.6 版新功能: 1


email 包中的中心类是 EmailMessage 类,从 email.message 模块导入。 它是 email 对象模型的基类。 EmailMessage 提供设置和查询标题字段、访问消息正文以及创建或修改结构化消息的核心功能。

电子邮件消息由 标头有效负载 (也称为 内容 )组成。 标头是 RFC 5322RFC 6532 样式的字段名称和值,其中字段名称和值由冒号分隔。 冒号不是字段名称或字段值的一部分。 有效载荷可以是简单的文本消息、二进制对象或结构化的子消息序列,每个子消息都有自己的一组标头和自己的有效载荷。 后一种类型的有效载荷由具有 MIME 类型的消息指示,例如 multipart/*message/rfc822

EmailMessage 对象提供的概念模型是一个有序的标头字典和一个 payload 表示 RFC 5322 正文的概念模型的消息,这可能是子 EmailMessage 对象的列表。 除了用于访问标头名称和值的普通字典方法之外,还有用于从标头访问专用信息(例如 MIME 内容类型)、用于操作有效载荷、用于生成消息的序列化版本以及用于递归遍历对象树。

EmailMessage 类字典接口由标头名称索引,标头名称必须是 ASCII 值。 字典的值是带有一些额外方法的字符串。 标题以保留大小写的形式存储和返回,但字段名称不区分大小写匹配。 与真正的字典不同,键是有顺序的,并且可以有重复的键。 提供了其他方法来处理具有重复键的标头。

payload 是字符串或字节对象(对于简单消息对象)或 EmailMessage 对象列表,对于 MIME 容器文档,例如 multipart/*[ X192X] 和 message/rfc822 消息对象。

class email.message.EmailMessage(policy=default)

如果指定了 policy,则使用它指定的规则来更新和序列化消息的表示。 如果未设置 policy,请使用 default 策略,该策略遵循电子邮件 RFC 的规则,但行尾除外(而不是 RFC 强制要求的 \r\n,它使用Python 标准 \n 行尾)。 有关更多信息,请参阅 policy 文档。

as_string(unixfrom=False, maxheaderlen=None, policy=None)

以字符串形式返回整条消息。 当可选 unixfrom 为 true 时,信封头包含在返回的字符串中。 unixfrom 默认为 False。 为了向后兼容基本 Messagemaxheaderlen 被接受,但默认为 None,这意味着默认情况下,行长度由 [ X195X] 的政策。 policy 参数可用于覆盖从消息实例获得的默认策略。 这可用于控制该方法生成的某些格式,因为指定的 policy 将传递给 Generator

如果需要填充默认值以完成到字符串的转换(例如,可能会生成或修改 MIME 边界),则扁平化消息可能会触发对 EmailMessage 的更改。

请注意,提供此方法是为了方便,可能不是在应用程序中序列化消息的最有用方法,尤其是在处理多条消息时。 请参阅 email.generator.Generator 以获得用于序列化消息的更灵活的 API。 另请注意,当 utf8False(这是默认值)时,此方法仅限于生成序列化为“7 位清洁”的消息。

在 3.6 版更改:未指定 maxheaderlen 时的默认行为从默认为 0 更改为默认为策略中的 max_line_length 的值。

__str__()

相当于 as_string(policy=self.policy.clone(utf8=True))。 允许 str(msg) 以可读格式生成包含序列化消息的字符串。

3.4 版更改: 方法改为使用 utf8=True,从而产生一个 RFC 6531-like 消息表示,而不是一个as_string() 的直接别名。

as_bytes(unixfrom=False, policy=None)

返回整条消息扁平化为字节对象。 当可选 unixfrom 为 true 时,信封头包含在返回的字符串中。 unixfrom 默认为 Falsepolicy 参数可用于覆盖从消息实例获得的默认策略。 这可用于控制该方法生成的某些格式,因为指定的 policy 将传递给 BytesGenerator

如果需要填充默认值以完成到字符串的转换(例如,可能会生成或修改 MIME 边界),则扁平化消息可能会触发对 EmailMessage 的更改。

请注意,提供此方法是为了方便,可能不是在应用程序中序列化消息的最有用方法,尤其是在处理多条消息时。 请参阅 email.generator.BytesGenerator 以获取更灵活的用于序列化消息的 API。

__bytes__()

相当于 as_bytes()。 允许 bytes(msg) 生成一个包含序列化消息的字节对象。

is_multipart()

如果消息的有效负载是子 EmailMessage 对象的列表,则返回 True,否则返回 False。 当 is_multipart() 返回 False 时,负载应该是字符串对象(可能是 CTE 编码的二进制负载)。 请注意,is_multipart() 返回 True 并不一定意味着“msg.get_content_maintype() == 'multipart'”将返回 True。 例如,当 EmailMessage 的类型为 message/rfc822 时,is_multipart 将返回 True

set_unixfrom(unixfrom)

将消息的信封头设置为 unixfrom,它应该是一个字符串。 (有关此标头的简要说明,请参阅 mboxMessage。)

get_unixfrom()

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

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

这些语义差异是有意的,在最常见的用例中偏向于方便。

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

__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() 方法获取名为 name 的所有现存头文件的值。

使用标准(非 compat32)策略,返回值是 email.headerregistry.BaseHeader 子类的实例。

__setitem__(name, val)

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

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

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

如果 policy 将某些标头定义为唯一的(如标准策略所做的那样),则当尝试为此类标头分配值时,此方法可能会引发 ValueError存在。 为了一致性起见,这种行为是有意的,但不要依赖它,因为我们可能会选择使此类分配在将来自动删除现有标头。

__delitem__(name)

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

keys()

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

values()

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

items()

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

get(name, failobj=None)

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

以下是一些额外的有用的标题相关方法:

get_all(name, failobj=None)

返回名为 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),以及 [ X367X] 是包含非 ASCII 代码点的字符串值。 如果未传递三元组且值包含非 ASCII 字符,则使用 utf-8CHARSET 自动编码为 RFC 2231 格式] 和 NoneLANGUAGE

下面是一个例子:

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'))
replace_header(_name, _value)

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

get_content_type()

返回消息的内容类型,强制为 maintype/subtype 形式的小写。 如果消息中没有 Content-Type 标头,则返回 get_default_type() 返回的值。 如果 Content-Type 标头无效,则返回 text/plain

(根据 RFC 2045,消息总是有一个默认类型,get_content_type() 总是会返回一个值。 RFC 2045 将消息的默认类型定义为 text/plain,除非它出现在 multipart/digest 容器中,在这种情况下它将是 消息/rfc822。 如果 Content-Type 标头的类型规范无效,则 RFC 2045 要求默认类型为 text/plain。)

get_content_maintype()

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

get_content_subtype()

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

get_default_type()

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

set_default_type(ctype)

设置默认内容类型。 ctype 应该是 text/plainmessage/rfc822,尽管这不是强制执行的。 默认内容类型不存储在 Content-Type 标头中,因此它仅在不存在 Content-Type 标头时影响 get_content_type 方法的返回值在消息中。

set_param(param, value, header='Content-Type', requote=True, charset=None, language=, replace=False)

Content-Type 标头中设置参数。 如果该参数已存在于标头中,则将其值替换为 value。 当 headerContent-Type(默认)且消息中尚不存在该头时,添加它,将其值设置为 text/plain,并附加新的参数值。 可选的 header 指定 Content-Type 的替代标头。

如果该值包含非 ASCII 字符,则可以使用可选的 charsetlanguage 参数显式指定字符集和语言。 可选 language 指定 RFC 2231 语言,默认为空字符串。 charsetlanguage 都应该是字符串。 默认是使用 utf8 charsetNone 作为 language

如果 replaceFalse(默认值),则标题将移动到标题列表的末尾。 如果 replaceTrue,则标题将就地更新。

不推荐将 requote 参数与 EmailMessage 对象一起使用。

请注意,可以通过标头值的 params 属性(例如,msg['Content-Type'].params['charset'])访问标头的现有参数值。

3.4 版更改:添加了 replace 关键字。

del_param(param, header='content-type', requote=True)

Content-Type 标头中完全删除给定的参数。 标头将在没有参数或其值的情况下重写。 可选的 header 指定了 Content-Type 的替代。

不推荐将 requote 参数与 EmailMessage 对象一起使用。

get_filename(failobj=None)

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

get_boundary(failobj=None)

返回消息的 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 标头在标头列表中的顺序。

get_content_charset(failobj=None)

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

get_charsets(failobj=None)

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

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

is_attachment()

如果存在 Content-Disposition 标头且其(不区分大小写)值为 attachment,则返回 True,否则返回 False

在 3.4.2 版更改:is_attachment 现在是一个方法而不是一个属性,与 is_multipart() 保持一致。

get_content_disposition()

返回消息的 Content-Disposition 标头的小写值(不带参数)(如果有),或 None。 如果消息遵循 RFC 2183,则此方法的可能值为 inlineattachmentNone

3.5 版中的新功能。

以下方法涉及询问和操纵消息的内容(有效载荷)。

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
text/plain

walk 迭代任何部分的子部分,其中 is_multipart() 返回 True,即使 msg.get_content_maintype() == 'multipart' 可能返回 False。 我们可以通过使用 _structure 调试辅助函数在我们的示例中看到这一点:

>>> from email.iterators import _structure
>>> for part in msg.walk():
...     print(part.get_content_maintype() == 'multipart',
...           part.is_multipart())
True True
False False
False True
False False
False False
False True
False False
>>> _structure(msg)
multipart/report
    text/plain
    message/delivery-status
        text/plain
        text/plain
    message/rfc822
        text/plain

这里的 message 部分不是 multiparts,但它们确实包含子部分。 is_multipart() 返回 Truewalk 下降到子部分。

get_body(preferencelist=('related', 'html', 'plain'))

返回最适合作为邮件“正文”的 MIME 部分。

preferencelist 必须是集合 relatedhtmlplain 中的字符串序列,并指示对内容类型的偏好顺序部分退回。

开始寻找与调用 get_body 方法的对象的候选匹配项。

如果 related 未包含在 preferencelist 中,如果(子)部分与首选项匹配,则将遇到的任何相关的根部分(或根部分的子部分)视为候选。

当遇到 multipart/related 时,检查 start 参数,如果找到匹配 Content-ID 的部分,则在寻找候选匹配时仅考虑它。 否则只考虑 multipart/related 的第一个(默认根)部分。

如果部件具有 Content-Disposition 标头,则仅当标头的值为 inline 时才将该部件视为候选匹配项。

如果没有候选人匹配 preferencelist 中的任何首选项,则返回 None

注意: (1) 对于大多数应用程序,唯一真正有意义的 preferencelist 组合是 ('plain',)('html', 'plain') 和默认的 ('related', 'html', 'plain')。 (2) 因为匹配是从调用 get_body 的对象开始的,所以在 multipart/related 上调用 get_body 将返回对象本身,除非 preferencelist 有一个非默认值。 (3) 未指定 Content-Type 或其 Content-Type 标头无效的消息(或消息部分)将被视为类型 [ X169X],这可能偶尔会导致 get_body 返回意外结果。

iter_attachments()

在消息的所有不是候选“正文”部分的直接子部分上返回一个迭代器。 也就是说,跳过 text/plaintext/htmlmultipart/relatedmultipart/alternative 中每一个的第一次出现(除非它们通过 明确标记为附件)内容处置:附件),并返回所有剩余部分。 当直接应用于 multipart/related 时,返回除根部分之外的所有相关部分的迭代器(即:start 参数指向的部分,如果没有,则返回第一部分) start 参数或 start 参数与任何部分的 Content-ID 不匹配)。 当直接应用于 multipart/alternative 或非 multipart 时,返回一个空迭代器。

iter_parts()

在消息的所有直接子部分上返回一个迭代器,对于非 multipart,它将为空。 (另见 walk()。)

get_content(*args, content_manager=None, **kw)

调用 content_managerget_content() 方法,将 self 作为消息对象传递,并将任何其他参数或关键字作为附加参数传递。 如果未指定content_manager,则使用当前policy指定的content_manager

set_content(*args, content_manager=None, **kw)

调用 content_managerset_content() 方法,将 self 作为消息对象传递,并将任何其他参数或关键字作为附加参数传递。 如果未指定content_manager,则使用当前policy指定的content_manager

make_related(boundary=None)

将非 multipart 消息转换为 multipart/related 消息,将任何现有的 Content- 标头和有效载荷移动到 multipart 的(新)第一部分. 如果指定了boundary,则将其作为multipart中的边界字符串,否则保留边界在需要时(例如消息序列化时)自动创建。

make_alternative(boundary=None)

将非 multipartmultipart/related 转换为 multipart/alternative,将任何现有的 Content- 标头和有效载荷移动到(新的)第一部分multipart。 如果指定了boundary,则将其作为multipart中的边界字符串,否则保留边界在需要时(例如消息序列化时)自动创建。

make_mixed(boundary=None)

将非 multipartmultipart/relatedmultipart-alternative 转换为 multipart/mixed,移动任何现有的 Content- 标头和有效载荷进入 multipart 的(新)第一部分。 如果指定了boundary,则将其作为multipart中的边界字符串,否则保留边界在需要时(例如消息序列化时)自动创建。

add_related(*args, content_manager=None, **kw)

如果消息是 multipart/related,则创建一个新消息对象,将所有参数传递给其 set_content() 方法,并将 attach() 传递给 [ X156X]。 如果消息是非 multipart,则调用 make_related(),然后按上述操作。 如果消息是任何其他类型的 multipart,则引发 TypeError。 如果未指定content_manager,则使用当前policy指定的content_manager。 如果添加的部分没有 Content-Disposition 标头,则添加一个值为 inline 的标头。

add_alternative(*args, content_manager=None, **kw)

如果消息是 multipart/alternative,则创建一个新消息对象,将所有参数传递给其 set_content() 方法,并将 attach() 传递给 [ X156X]。 如果消息是非 multipartmultipart/related,请调用 make_alternative(),然后按上述操作。 如果消息是任何其他类型的 multipart,则引发 TypeError。 如果未指定content_manager,则使用当前policy指定的content_manager

add_attachment(*args, content_manager=None, **kw)

如果消息是 multipart/mixed,则创建一个新消息对象,将所有参数传递给其 set_content() 方法,并将 attach() 传递给 [ X156X]。 如果消息是非 multipartmultipart/relatedmultipart/alternative,请调用 make_mixed(),然后按上述操作。 如果未指定content_manager,则使用当前policy指定的content_manager。 如果添加的部分没有 Content-Disposition 标头,则添加一个值为 attachment 的标头。 通过将适当的选项传递给content_manager

clear()

删除有效负载和所有标头。

clear_content()

删除有效负载和所有 Content- 标头,保留所有其他标头完整并按其原始顺序。

EmailMessage 对象具有以下实例属性:

preamble

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

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

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

epilogue

epilogue 属性的作用与 preamble 属性相同,不同之处在于它包含出现在消息最后边界和结尾之间的文本。 与 preamble 一样,如果没有结语文本,该属性将为 None

defects

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

class email.message.MIMEPart(policy=default)
此类表示 MIME 消息的子部分。 它与 EmailMessage 相同,除了在调用 set_content() 时不添加 MIME-Version 头,因为子部分不需要自己的 [ X174X]MIME-Version 标头。

脚注

1
最初在 3.4 中作为 临时模块 添加。 旧邮件类的文档移至 email.message.Message:使用 compat32 API 表示电子邮件。