email.message.Message :表示使用 compat32 API

这个 Message 类与 EmailMessage 类,没有该类添加的方法,并且某些其他方法的默认行为略有不同。我们在这里还记录了一些方法,这些方法在 EmailMessage 除非处理旧代码,否则不建议使用类。

这两个阶级的哲学和结构在其他方面是相同的。

本文档描述了默认情况下的行为(对于 Message 政策 Compat32 .如果要使用其他策略,则应使用 EmailMessage 改为类。

电子邮件包含 headers 和A payload . 报头必须是 RFC 5233 样式名和值,其中字段名和值由冒号分隔。冒号不是字段名或字段值的一部分。有效负载可以是简单的文本消息,或者二进制对象,或者子消息的结构化序列,每个子消息都有自己的头集和自己的有效负载。后一种类型的有效负载由具有mime类型的消息指示,例如 multipart/*message/rfc822 .

A提供的概念模型 Message 对象是一个有序的头字典,它具有从头访问两个专用信息、访问有效负载、生成消息的序列化版本以及递归遍历对象树的附加方法。请注意,支持重复的头,但必须使用特殊方法来访问它们。

这个 Message 伪字典是由头名称索引的,头名称必须是ASCII值。字典的值是应该只包含ASCII字符的字符串;对于非ASCII输入有一些特殊的处理,但它并不总是产生正确的结果。头以大小写保留形式存储和返回,但字段名不区分大小写匹配。也可能有一个单独的信封头,也称为 Unix-From 标题或 From_ 标题。这个 payload 是字符串或字节(对于简单消息对象)或 Message 对象,用于mime容器文档(例如 multipart/*message/rfc822

以下是 Message 类:

class email.message.Message(policy=compat32)

如果 policy 已指定(它必须是 policy 类)使用它指定的规则更新和序列化消息的表示形式。如果 policy 未设置,请使用 compat32 策略,它与电子邮件包的python 3.2版本保持向后兼容性。有关更多信息,请参阅 policy 文档。

在 3.3 版更改: 这个 policy 已添加关键字参数。

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

返回整个扁平化为字符串的消息。当可选时 unixfrom 为真,信封头包含在返回的字符串中。 unixfrom 默认为 False . 出于向后兼容性的原因, 麦克海德伦 默认为 0 ,因此,如果需要不同的值,则必须显式重写它(为指定的值 max_line_length 在策略中,将被此方法忽略)。这个 policy 参数可用于重写从消息实例获取的默认策略。由于指定了 policy 将传递给 Generator .

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

请注意,此方法是为了方便起见而提供的,可能并不总是以您想要的方式格式化消息。例如,默认情况下,它不会对以 From 这是unix mbox格式所必需的。为了获得更大的灵活性,请实例化 Generator 实例并使用其 flatten() 方法直接。例如::

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

如果消息对象包含未按照RFC标准编码的二进制数据,则不符合要求的数据将被Unicode“未知字符”代码点替换。(也见) as_bytes()BytesGenerator

在 3.4 版更改: 这个 policy 已添加关键字参数。

__str__()

相当于 as_string() . 允许 str(msg) 生成包含格式化消息的字符串。

as_bytes(unixfrom=False, policy=None)

返回整个扁平化为字节对象的消息。可选时 unixfrom 为真,信封头包含在返回的字符串中。 unixfrom 默认为 False . 这个 policy 参数可用于重写从消息实例获取的默认策略。由于指定了 policy 将传递给 BytesGenerator .

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

请注意,此方法是为了方便起见而提供的,可能并不总是以您想要的方式格式化消息。例如,默认情况下,它不会对以 From 这是unix mbox格式所必需的。为了获得更大的灵活性,请实例化 BytesGenerator 实例并使用其 flatten() 方法直接。例如::

from io import BytesIO
from email.generator import BytesGenerator
fp = BytesIO()
g = BytesGenerator(fp, mangle_from_=True, maxheaderlen=60)
g.flatten(msg)
text = fp.getvalue()

3.4 新版功能.

__bytes__()

相当于 as_bytes() . 允许 bytes(msg) 生成包含格式化消息的bytes对象。

3.4 新版功能.

is_multipart()

返回 True 如果消息的有效负载是SUB的列表-Message 对象,否则返回 False .什么时候? is_multipart() 返回 False ,有效负载应该是字符串对象(可能是CTE编码的二进制有效负载)。(注意 is_multipart() 返回 True 不一定意味着“msg.get_content_maintype()=‘multipart’”将返回 True . 例如, is_multipart 将返回 TrueMessage 属于类型 message/rfc822

set_unixfrom(unixfrom)

将邮件的信封头设置为 unixfrom ,应为字符串。

get_unixfrom()

返回邮件的信封头。默认为 None 如果没有设置信封头。

attach(payload)

添加给定的 payload 当前有效载荷,必须 None 或一览表 Message 调用前的对象。调用后,有效负载将始终是 Message 物体。如果要将有效负载设置为标量对象(例如字符串),请使用 set_payload() 相反。

这是一个遗留方法。上 EmailMessage 类,其功能替换为 set_content() 及相关 makeadd 方法。

get_payload(i=None, decode=False)

返回当前有效载荷,它是 Message 对象何时 is_multipart()True 或字符串 is_multipart()False . 如果有效负载是一个列表,并且您改变了列表对象,那么您可以在适当的位置修改消息的有效负载。

带可选参数 iget_payload() 将返回 i -有效载荷的第个元素,从零开始计数,如果 is_multipart()True . 安 IndexError 如果 i 小于0或大于或等于负载中的项数。如果有效载荷是一个字符串(即 is_multipart()Falsei 给出了 TypeError 提高了。

可选的 decode 是一个标志,根据 Content-Transfer-Encoding 标题。什么时候? True 消息不是多部分的,如果头的值为 quoted-printablebase64 . 如果使用其他编码,或 Content-Transfer-Encoding 头丢失,有效负载按原样返回(未编码)。在所有情况下,返回的值都是二进制数据。如果消息是多部分的,并且 decode 旗是 True 然后 None 返回。如果有效负载是base64,并且其格式不完全(缺少填充、base64字母之外的字符),那么将向消息的缺陷属性添加适当的缺陷。 (InvalidBase64PaddingDefectInvalidBase64CharactersDefect ,分别)。

什么时候? decodeFalse (默认值)正文作为字符串返回,而不解码 Content-Transfer-Encoding . 然而,对于 Content-Transfer-Encoding 在8bit中,尝试使用 charset 由指定 Content-Type 标题,使用 replace 错误处理程序。如果没有 charset 是指定的,或者如果 charset 给定的不被电子邮件包识别,正文使用默认的ASCII字符集进行解码。

这是一个遗留方法。上 EmailMessage 类,其功能替换为 get_content()iter_parts() .

set_payload(payload, charset=None)

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

这是一个遗留方法。上 EmailMessage 类,其功能替换为 set_content() .

set_charset(charset)

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

如果不存在 MIME-Version 将添加标题1。如果不存在 Content-Type 标题,将添加一个值为 text/plain . 是否 Content-Type 头是否已存在,其 charset 参数将设置为 charset.output_charset . 如果 charset.input_charsetcharset.output_charset 不同的是,有效载荷将重新编码到 output_charset . 如果不存在 Content-Transfer-Encoding 如果需要,则使用指定的 Charset ,并添加具有适当值的标题。如果A Content-Transfer-Encoding 头已经存在,假定负载已经使用该头正确编码 Content-Transfer-Encoding 并且不被修改。

这是一个遗留方法。上 EmailMessage 类的功能被替换为 charset 的参数 email.emailmessage.EmailMessage.set_content() 方法。

get_charset()

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

这是一个遗留方法。上 EmailMessage 类它总是返回 None .

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

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

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

在由字节生成的模型中,任何包含非ASCII字节的头值(违反RFC)在通过该接口检索时都将表示为 Header 字符集为的对象 unknown-8bit .

__len__()

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

__contains__(name)

返回 True 如果消息对象有一个名为 name . 匹配是不敏感的,并且 name 不应包括尾随冒号。用于 in 操作员,例如:

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

返回命名头字段的值。 name 不应包括冒号字段分隔符。如果缺少标题, None 返回;A KeyError 从未被引发。

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

__setitem__(name, val)

在邮件中添加域名 name 价值 val . 该字段将附加到消息现有字段的末尾。

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

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

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

keys()

返回所有邮件头字段名的列表。

values()

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

items()

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

get(name, failobj=None)

返回命名头字段的值。这和 __getitem__() 除了那个可选的 故障对象 如果缺少命名头,则返回(默认为 None

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

get_all(name, failobj=None)

返回名为的字段的所有值的列表 name . 如果消息中没有这样的命名头, 故障对象 返回(默认为 None

add_header(_name, _value, **_params)

扩展头段设置。这种方法类似于 __setitem__() 除了可以将其他头参数作为关键字参数提供。 _name 是要添加的标题字段,并且 _value初级的 标题的值。

对于关键字参数字典中的每个项 _params ,键作为参数名,下划线转换为破折号(因为破折号在Python标识符中是非法的)。通常,参数将添加为 key="value" 除非值是 None ,在这种情况下,只添加密钥。如果值包含非ASCII字符,则可以将其指定为格式中的三元组。 (CHARSET, LANGUAGE, VALUE) 在哪里 CHARSET 是一个字符串,命名用于对值进行编码的字符集, LANGUAGE 通常可以设置为 None 或空字符串(请参见 RFC 2231 其他可能性),以及 VALUE 是包含非ASCII码位的字符串值。如果未传递三元组,且值包含非ASCII字符,则会自动将其编码为 RFC 2231 格式使用 CHARSET 属于 utf-8 和A LANGUAGE 属于 None .

举个例子:

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 提高了。

get_content_type()

返回消息的内容类型。返回的字符串被强制为窗体的小写 maintype/subtype . 如果没有 Content-Type 消息头中的默认类型 get_default_type() 将被退回。因为根据 RFC 2045 ,消息始终具有默认类型, get_content_type() 将始终返回值。

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

get_content_maintype()

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

get_content_subtype()

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

get_default_type()

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

set_default_type(ctype)

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

get_params(failobj=None, header='content-type', unquote=True)

返回邮件的 Content-Type 参数,作为列表。返回列表的元素是键/值对的2个元组,如在 '=' 符号。的左侧 '=' 是键,而右侧是值。如果没有 '=' 在参数中签名该值为空字符串,否则该值如中所述 get_param() 如果可选,则不加引号。 不引用True (默认值)。

可选的 故障对象 如果没有 Content-Type 标题。可选的 *header*是要搜索的标题而不是 Content-Type .

这是一个遗留方法。上 EmailMessage 类的功能被替换为 帕拉姆 头访问方法返回的单个头对象的属性。

get_param(param, failobj=None, header='content-type', unquote=True)

返回的值 Content-Type 标题参数 帕拉姆 作为字符串。如果消息没有 Content-Type 头,或者如果没有这样的参数,那么 故障对象 返回(默认为 None

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

参数键总是不敏感地进行大小写比较。返回值可以是字符串,也可以是3元组(如果参数为 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)

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

这是一个遗留方法。上 EmailMessage 类的功能被替换为 帕拉姆 头访问方法返回的单个头对象的属性。

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

在中设置参数 Content-Type 标题。如果参数已存在于头中,则其值将替换为 value . 如果 Content-Type 尚未为此消息定义头,它将被设置为 text/plain 新参数值将根据 RFC 2045 .

可选的 header*指定的可选标题 :mailheader:`Content-Type` ,所有参数将根据需要进行报价,除非可选。 *请求False (默认为 True

如果可选 charset 如果指定,参数将根据 RFC 2231 . 可选的 语言 指定RFC 2231语言,默认为空字符串。两个 charset语言 应该是字符串。

如果 代替False (默认设置)标题将移动到标题列表的末尾。如果 代替True ,标题将就地更新。

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

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

从中完全删除给定参数 Content-Type 标题。头将在没有参数或其值的情况下重新写入。所有数值将根据需要进行报价,除非 请求False (默认为 True )可选的 *header*指定替代 Content-Type .

set_type(type, header='Content-Type', requote=True)

设置的主类型和子类型 Content-Type 标题。 type 必须是窗体中的字符串 maintype/subtype ,否则 ValueError 提高了。

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

可以在 *header*参数。当 Content-Type 标题设置为 MIME-Version 还添加了标题。

这是一个遗留方法。上 EmailMessage 类的功能被替换为 make_add_ 方法。

get_filename(failobj=None)

返回的值 filename 的参数 Content-Disposition 消息的标题。如果标题没有 filename 参数,此方法返回到查找 name 上的参数 Content-Type 标题。如果两者都找不到,或者头丢失,则 故障对象 返回。返回的字符串将始终按照 email.utils.unquote() .

get_boundary(failobj=None)

返回的值 boundary 的参数 Content-Type 消息头,或 故障对象 如果头丢失或没有 boundary 参数。返回的字符串将始终按照 email.utils.unquote() .

set_boundary(boundary)

设置 boundary 的参数 Content-Type 报头到 边界 . set_boundary() 将始终引用 边界 如有必要。一 HeaderParseError 如果消息对象没有 Content-Type 标题。

请注意,使用此方法与删除旧的 Content-Type 标题并通过添加新边界的新标题 add_header() ,因为 set_boundary() 保留 Content-Type 标题列表中的标题。但是,它确实 not 保留原始文件中可能存在的任何续行 Content-Type 标题。

get_content_charset(failobj=None)

返回 charset 的参数 Content-Type 头,强制降低大小写。如果没有 Content-Type 头,或者如果头没有 charset 参数, 故障对象 返回。

请注意,此方法与 get_charset() 它返回 Charset 消息体的默认编码的实例。

get_charsets(failobj=None)

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

列表中的每个项都将是一个字符串,该字符串是 charset 中的参数 Content-Type 所代表子部分的标题。但是,如果子部分没有 Content-Type 页眉,没有 charset 参数,或不是 text 主mime类型,则返回列表中的该项将 故障对象 .

get_content_disposition()

返回消息的低基值(不带参数) Content-Disposition 头(如果有),或 None . 此方法的可能值为 内联的附件None 如果信息如下 RFC 2183 .

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 调试助手函数:

>>> 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 下降到子部分。

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

preamble

MIME文档的格式允许在标题后面的空白行和第一个多部分边界字符串之间有一些文本。通常,此文本在支持mime的邮件阅读器中是不可见的,因为它不属于标准mime保护层。但是,在查看消息的原始文本时,或者在不支持mime的读卡器中查看消息时,可以看到此文本。

这个 序言 属性包含用于mime文档的这种前导的额外护甲文本。当 Parser 在头之后但在第一个边界字符串之前发现一些文本,它将此文本分配给消息的 序言 属性。当 Generator 正在写出一个mime消息的纯文本表示,它发现该消息具有 序言 属性,它将在标题和第一个边界之间的区域中写入此文本。见 email.parseremail.generator 有关详细信息。

请注意,如果message对象没有前导码,则 序言 属性将为 None .

epilogue

这个 后记 属性的作用方式与 序言 属性,但它包含出现在最后一个边界和消息结尾之间的文本。

您不需要将尾声设置为空字符串, Generator 在文件末尾打印新行。

defects

这个 缺陷 属性包含分析此消息时发现的所有问题的列表。见 email.errors 有关可能的分析缺陷的详细描述。