On this page
email.message.Message:使用 compat32 API 表示电子邮件
Message类与EmailMessage类非常相似,没有该类添加的方法,并且某些其他方法的默认行为略有不同。我们还在此处记录了EmailMessage类支持的一些方法,除非您要处理旧代码,否则建议不要使用这些方法。
这两类的哲学和结构在其他方面是相同的。
本文档介绍了默认(针对Message)策略Compat32的行为。如果要使用其他策略,则应改用EmailMessage类。
电子邮件由* header 和 payload 组成。Headers 必须为 RFC 5233个样式名称和值,其中字段名称和值之间用冒号分隔。冒号既不是字段名也不是字段值的一部分。有效负载可以是简单的文本消息,也可以是二进制对象,也可以是子消息的结构化序列,每个子消息都具有自己的 Headers 集和自己的有效负载。有效负载的后一种类型由具有 MIME 类型的消息(例如 multipart/*或 message/rfc822 *)指示。
Message对象提供的概念模型是标题的有序字典,其中包含用于从标题访问专用信息,访问有效负载,生成消息的序列化版本以及递归遍历对象树的其他方法。请注意,支持重复的 Headers,但必须使用特殊的方法来访问它们。
Message伪词典由 Headers 名称索引,Headers 名称必须为 ASCII 值。字典的值是应该仅包含 ASCII 字符的字符串;非 ASCIIImporting 有一些特殊的处理方法,但它并不总是产生正确的结果。Headers 以保留大小写的形式存储和返回,但是字段名称不区分大小写。也可能只有一个信封 Headers,也称为* Unix-From Headers 或From_
Headers。如果是简单的邮件对象,则 payload 可以是字符串或字节,对于 MIME 容器文档(例如 multipart/*和 message/rfc822 ), payload 可以是字符串,也可以是Message对象的列表。
以下是Message类的方法:
- 类别
email.message.
Message
(* policy = compat32 *)
在版本 3.3 中更改:添加了* policy *关键字参数。
as_string
(* unixfrom = False , maxheaderlen = 0 , policy = None *)- 返回整平为字符串的整个消息。当可选的* unixfrom *为 true 时,信封头包含在返回的字符串中。 * unixfrom 默认为
False
。出于向后兼容的原因, maxheaderlen 默认为0
,因此,如果要使用其他值,则必须显式覆盖它(此方法将忽略策略中为 max_line_length *指定的值)。 * policy 参数可用于覆盖从消息实例获得的默认策略。由于指定的 policy *将传递给Generator
,因此可以用来控制该方法产生的某些格式。
- 返回整平为字符串的整个消息。当可选的* unixfrom *为 true 时,信封头包含在返回的字符串中。 * unixfrom 默认为
如果需要填写默认值以完成对字符串的转换(例如,可能会生成或修改 MIME 边界),则拼合消息可能会触发对Message的更改。
请注意,此方法是为方便起见而提供的,不一定总是按照您想要的方式格式化消息。例如,默认情况下,它不对 unix mbox 格式要求的以From
开头的行进行处理。为了获得更大的灵 Active,请实例化一个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_string()。允许
as_bytes
(* unixfrom = False , policy = None *)- 返回展平为字节对象的整个消息。当可选的* unixfrom *为 true 时,信封头包含在返回的字符串中。 * unixfrom *默认为
False
。 * policy 参数可用于覆盖从消息实例获得的默认策略。由于指定的 policy *将传递给BytesGenerator
,因此可以用来控制该方法产生的某些格式。
- 返回展平为字节对象的整个消息。当可选的* unixfrom *为 true 时,信封头包含在返回的字符串中。 * unixfrom *默认为
如果需要填写默认值以完成对字符串的转换(例如,可能会生成或修改 MIME 边界),则拼合消息可能会触发对Message的更改。
请注意,此方法是为方便起见而提供的,不一定总是按照您想要的方式格式化消息。例如,默认情况下,它不对 unix mbox 格式要求的以From
开头的行进行处理。为了获得更大的灵 Active,请实例化一个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 版的新Function。
__bytes__
( )- 等效于as_bytes()。允许
bytes(msg)
产生一个包含格式化消息的字节对象。
- 等效于as_bytes()。允许
3.4 版的新Function。
is_multipart
( )- 如果消息的有效负载是子Message对象的列表,则返回
True
,否则返回False
。当is_multipart()返回False
时,有效负载应为字符串对象(可能是 CTE 编码的二进制有效负载)。 (请注意,is_multipart()返回True
并不一定意味着“ msg.get_content_maintype()=='multipart'”将返回True
。例如,当Message类型为message/rfc822
时,is_multipart
将返回True
。)
- 如果消息的有效负载是子Message对象的列表,则返回
set_unixfrom
(* unixfrom *)- 将邮件的信封 Headers 设置为* unixfrom *,它应该是一个字符串。
get_unixfrom
( )- 返回邮件的信封头。如果从未设置信封头,则默认为
None
。
- 返回邮件的信封头。如果从未设置信封头,则默认为
attach
(有效负载)- 将给定的* payload *添加到当前有效负载中,该有效负载必须为
None
或调用之前的Message对象列表。调用之后,有效负载将始终是Message个对象的列表。如果要将有效负载设置为标量对象(例如字符串),请改用set_payload()。
- 将给定的* payload *添加到当前有效负载中,该有效负载必须为
这是传统方法。在EmailMessage
类上,其Function由set_content()以及相关的make
和add
方法代替。
get_payload
(* i = None , decode = False *)- 返回当前有效负载,当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,则将按原样返回有效负载(未编码)。在所有情况下,返回值都是二进制数据。如果消息是 Multipart 消息,并且 decode *标志是True
,则返回None
。如果有效载荷是 base64 且格式不正确(缺少填充,base64 字母之外的字符),则会将适当的缺陷添加到消息的缺陷属性(分别为InvalidBase64PaddingDefect
或InvalidBase64CharactersDefect
)。
当* decode 为False
(默认值)时,主体将作为字符串返回,而不对 Content-Transfer-Encoding 进行解码。但是,对于 8 位的 Content-Transfer-Encoding ,try使用replace
错误处理程序,使用 Content-Type *Headers 指定的charset
解码原始字节。如果未指定charset
,或者电子邮件包无法识别给定的charset
,则使用默认的 ASCII 字符集对正文进行解码。
这是传统方法。在EmailMessage
类上,其Function由get_content()和iter_parts()代替。
set_payload
(有效负载,字符集=无)- 将整个消息对象的有效负载设置为* payload 。确保有效载荷不变是 Client 的责任。可选的 charset *设置消息的默认字符集;有关详情,请参见set_charset()。
这是传统方法。在EmailMessage
类上,其Function由set_content()代替。
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 *对有效负载进行了正确编码,并且未对其进行修改。
这是传统方法。在EmailMessage
类上,其Function由email.emailmessage.EmailMessage.set_content()
方法的* charset *参数代替。
get_charset
( )- 返回与消息的有效负载关联的Charset实例。
这是传统方法。在EmailMessage
类上,它总是返回None
。
下列方法实现了一个类似于 Map 的接口,用于访问消息的 RFC 2822Headers。请注意,这些方法与常规 Map(即字典)接口之间在语义上有所不同。例如,在词典中没有重复的键,但是这里可能有重复的消息头。同样,在字典中并没有保证keys()返回的键的 Sequences,但是在Message对象中,Headers 总是按照它们在原始消息中出现的 Sequences 返回,或者在以后添加到消息中。删除然后重新添加的任何 Headers 始终附加在 Headers 列表的末尾。
这些语义上的差异是故意的,并且倾向于最大的便利性。
请注意,在所有情况下,消息中存在的任何信封头都不会包含在 Map 接口中。
在从字节生成的模型中,任何pass非接口(与 RFC 违背)包含非 ASCII 字节的 Headers 值,当pass此接口检索时,都将被表示为Header对象,其字符集为 unknown-8bit。
__len__
( )- 返回标题总数,包括重复项。
__contains__
(* name *)- 如果消息对象具有名为* name 的字段,则返回
True
。匹配不区分大小写,并且 name *不应包含结尾的冒号。用于in
运算符,例如:
- 如果消息对象具有名为* 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 *的字段。如果标题字段中不存在命名字段,则不会引发异常。
keys
( )- 返回所有消息标题字段名称的列表。
values
( )- 返回所有消息字段值的列表。
items
( )- 返回一个包含所有消息字段标题和值的 2Tuples 列表。
get
(* name , failobj = None *)- 返回命名标题字段的值。这与getitem()相同,除了如果缺少指定的 Headers(默认为
None
),则返回可选的* failobj *。
- 返回命名标题字段的值。这与getitem()相同,除了如果缺少指定的 Headers(默认为
以下是一些其他有用的方法:
get_all
(* name , failobj = None *)- 返回名为* 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 代码点的字符串值。如果未传递三个 Tuples,并且该值包含非 ASCII 字符,则会使用utf-8
的CHARSET
和None
的LANGUAGE
自动以 RFC 2231格式进行编码。
这是一个例子:
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。
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 *。
get_content_maintype
( )- 返回消息的主要 Content Type。这是get_content_type()返回的字符串的* maintype *部分。
get_content_subtype
( )- 返回消息的子 Content Type。这是get_content_type()返回的字符串的* subtype *部分。
get_default_type
( )- 返回默认的 Content Type。大多数消息的默认 Content Type 为* text/plain ,但作为 multipart/digest 容器的子部分的消息除外。这些子部分的默认 Content Type 为 message/rfc822 *。
set_default_type
(* ctype *)- 设置默认的 Content Type。 * ctype 应该是 text/plain 或 message/rfc822 ,尽管这不是强制性的。默认 Content Type 未存储在 Content-Type *Headers 中。
get_params
(* failobj = None , header ='content-type', unquote = True *)- 以列表形式返回消息的* Content-Type 参数。返回列表的元素是键/值对的 2Tuples,在
'='
符号上拆分。'='
的左侧是键,而右侧是值。如果参数中没有'='
符号,则该值为空字符串,否则该值如get_param()中所述,并且如果可选的 unquote *为True
(默认值),则该值不加引号。
- 以列表形式返回消息的* Content-Type 参数。返回列表的元素是键/值对的 2Tuples,在
可选的* failobj 是没有 Content-Type 头时要返回的对象。可选的 header 是要搜索的标题,而不是 Content-Type *。
这是传统方法。在EmailMessage
类上,其Function由 Headers 访问方法返回的各个 Headers 对象的* params *属性代替。
get_param
(* param , failobj = None , header ='content-type', unquote = True *)- 以字符串形式返回* 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
项)始终不加引号。
这是传统方法。在EmailMessage
类上,其Function由 Headers 访问方法返回的各个 Headers 对象的* params *属性代替。
set_param
((param , value , header ='Content-Type', requote = True , charset = None , language ='', replace = False *)- 在* 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 *都应为字符串。
如果* replace 为False
(默认值),则标题将移动到标题列表的末尾。如果 replace *为True
,则标题将被适当更新。
在版本 3.4 中更改:添加了replace
关键字。
del_param
(* param , header ='content-type', requote = True *)- 从* Content-Type Headers 中完全删除给定的参数。Headers 将在没有参数或其值的情况下被重写。除非 requote 为
False
(默认值为True
),否则所有值都将根据需要加上引号。可选的 header 指定 Content-Type *的替代形式。
- 从* Content-Type Headers 中完全删除给定的参数。Headers 将在没有参数或其值的情况下被重写。除非 requote 为
set_type
(* type , header ='Content-Type', requote = True *)- 设置* Content-Type *Headers 的主要类型和子类型。 * type 必须是形式为 maintype/subtype *的字符串,否则引发ValueError。
此方法替换* Content-Type Headers,将所有参数保留在适当的位置。如果 requote *为False
,则保留现有 Headers 的引用不变,否则参数将被引用(默认)。
可以在* header 参数中指定备用标题。设置 Content-Type Headers 后,还将添加 MIME-Version *Headers。
这是传统方法。在EmailMessage
类上,其Function由make_
和add_
方法代替。
get_filename
(* failobj = None *)- 返回消息的* Content-Disposition Headers 的
filename
参数的值。如果标题没有filename
参数,则此方法将退回到在 Content-Type 标题上寻找name
参数。如果两者均未找到,或者标题丢失,则返回 failobj *。返回的字符串将始终按照email.utils.unquote()取消引用。
- 返回消息的* Content-Disposition Headers 的
get_boundary
(* failobj = None *)- 返回消息的* 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 = None *)- 返回* Content-Type Headers 的
charset
参数(强制小写)。如果没有 Content-Type 头,或者该头没有charset
参数,则返回 failobj *。
- 返回* Content-Type Headers 的
请注意,此方法不同于get_charset(),后者返回Charset实例以获取消息正文的默认编码。
get_charsets
(* failobj = None *)- 返回包含消息中字符集名称的列表。如果消息是* multipart *,则列表将为有效负载中的每个子部分包含一个元素,否则,它将为长度为 1 的列表。
列表中的每个项目都是一个字符串,它是表示子部分的* Content-Type 标题中charset
参数的值。但是,如果子部分没有 Content-Type Headers,没有charset
参数或者不是 text 主 MIME 类型,则返回列表中的该项将是 failobj *。
get_content_disposition
( )- 返回消息的* Content-Disposition Headers 的小写值(不带参数)(如果有的话)或
None
。如果消息遵循 RFC 2183,则此方法的可能值为 inline , attachment *或None
。
- 返回消息的* Content-Disposition Headers 的小写值(不带参数)(如果有的话)或
3.5 版中的新Function。
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
text/plain
walk
迭代is_multipart()返回True
的任何部分的子部分,即使msg.get_content_maintype() == 'multipart'
可能返回False
。我们可以pass使用_structure
debug helper 函数在示例中看到这一点:
>>> 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()
返回True
,walk
下降到子部分。
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 *属性相同,不同之处在于它包含出现在消息的最后边界和末尾之间的文本。
-
您无需将结尾部分设置为空字符串,即可使Generator在文件末尾打印换行符。
defects
-
- defects *属性包含解析此消息时发现的所有问题的列表。有关可能的解析缺陷的详细说明,请参见email.errors。
-