19.1.1. email.message
:表示电子邮件¶
email
包中的中心类是从email.message
模块导入的Message
类。它是email
对象模型的基类。Message
提供了设置和查询标头字段以及访问消息体的核心功能。
概念上,Message
对象由头和有效载荷组成。标头是 RFC 2822样式字段名称和值,其中字段名称和值由冒号分隔。冒号不是字段名称或字段值的一部分。
标题以保存形式存储和返回,但不区分大小写。还可以有单个包络头,也称为Unix-From头或From_
头。有效载荷是在简单消息对象的情况下的字符串或者对于MIME容器文档的Message
对象的列表。multipart / *和message / rfc822)。
Message
对象提供用于访问消息头的映射样式接口,以及用于访问头和净荷的显式接口。它提供了方便的方法来生成消息对象树的平面文本表示,用于访问常用的头参数,以及递归地遍历对象树。
以下是Message
类的方法:
- class
email.message.
Message
(policy=compat32)¶ 如果指定policy(它必须是
policy
类的实例),请使用它指定的规则来更新和序列化消息的表示。如果未设置策略,请使用compat32
策略,该策略与Python 3.2版本的电子邮件包保持向后兼容。有关详细信息,请参阅policy
文档。在版本3.3中已更改:添加了策略关键字参数。
-
as_string
(unixfrom=False, maxheaderlen=0, policy=None)¶ 返回全部消息以字符串的形式当可选unixfrom为真时,包络头将包含在返回的字符串中。unixfrom默认为
False
。对于向后合并的原因,maxheaderlen默认为0
,因此如果您想要不同的值,则必须明确覆盖它(max_line_length该策略将被此方法忽略)。policy参数可用于覆盖从消息实例获取的默认策略。这可以用于控制由该方法生成的某些格式,因为指定的策略将传递到Generator
。如果需要填写默认值以完成到字符串的转换(例如,可能生成或修改MIME边界),则对邮件进行平整可能会触发对
Message
的更改。请注意,此方法是为了方便而提供,可能并不总是按照您想要的方式格式化邮件。例如,默认情况下,它不会对以unix mbox格式所需的
From
开头的行进行修改。为了更灵活,实例化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中已更改: t>>添加了策略关键字参数。
-
__str__
()¶ 等效于
as_string()
。允许str(msg)
生成包含格式化消息的字符串。
-
as_bytes
(unixfrom=False, policy=None)¶ 返回作为字节对象展平的整个消息。当可选unixfrom为真时,包络头将包含在返回的字符串中。unixfrom默认为
False
。policy参数可用于覆盖从消息实例获取的默认策略。这可以用于控制由该方法生成的某些格式,因为指定的策略将传递到BytesGenerator
。如果需要填写默认值以完成到字符串的转换(例如,可能生成或修改MIME边界),则对邮件进行平整可能会触发对
Message
的更改。请注意,此方法是为了方便而提供,可能并不总是按照您想要的方式格式化邮件。例如,默认情况下,它不会对以unix mbox格式所需的
From
开头的行进行修改。为了更灵活,实例化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)
生成包含格式化消息的字节对象。版本3.4中的新功能。
-
is_multipart
()¶ 如果邮件的有效内容是sub
Message
对象的列表,则返回True
,否则返回False
。当is_multipart()
返回False
时,有效内容应为字符串对象。(请注意,is_multipart()
返回True
并不一定意味着“msg.get_content_maintype()=='multipart'”将返回True
。例如,当Message
类型为message/rfc822
时,is_multipart
将返回True
-
set_unixfrom
(unixfrom)¶ 将邮件的包络头设置为unixfrom,应为字符串。
-
get_unixfrom
()¶ 返回邮件的信封头如果信封标题从未设置,则默认为
None
。
-
attach
(payload)¶ 将给定的有效内容添加到当前有效内容,在调用前必须
None
或Message
对象列表。调用后,有效负载将始终是Message
对象的列表。如果要将有效负载设置为标量对象(例如,字符串),请改用set_payload()
。
-
get_payload
(i=None, decode=False)¶ 返回当
is_multipart()
为True
时,Message
对象的列表,或is_multipart()
是False
。如果有效载荷是一个列表,并且您改变列表对象,您就可以修改消息的有效载荷。使用可选参数i,
get_payload()
将返回有效负载的i元素,如果is_multipart()
是True
。如果i小于0或大于或等于有效载荷中的项目数,则会引发IndexError
。如果有效载荷是字符串(即,is_multipart()
是False
)和i时,会出现TypeError
。根据内容传输编码 t>头部,可选的解码是指示是否应当解码有效载荷的标志。当
True
且消息不是多部分时,如果此标头的值为quoted-printable
或base64
,则有效内容将被解码。如果使用某些其他编码,或者缺少Content-Transfer-Encoding头,则有效载荷按原样(未解码)返回。在所有情况下,返回的值都是二进制数据。如果消息是多部分且decode标志为True
,则返回None
。如果有效载荷是base64并且它没有完美形成(缺少填充,base64字母外的字符),则适当的缺陷将添加到消息的缺陷属性(InvalidBase64PaddingDefect
或InvalidBase64CharactersDefect
当解码为
False
(默认值)时,主体作为字符串返回,而不解码Content-Transfer-Encoding。但是,对于8比特的内容传输编码,尝试使用由内容类型指定的charset
>标头,使用replace
错误处理程序。如果未指定charset
,或者如果给定的charset
无法被电子邮件包识别,则使用默认的ASCII字符集解码正文。
-
set_payload
(payload, charset=None)¶ 将整个消息对象的有效内容设置为有效内容。确保有效载荷不变量是客户的责任。可选字符集设置消息的默认字符集;有关详细信息,请参阅
set_charset()
。
-
set_charset
(charset)¶ 将有效负载的字符集设置为charset,可以是
Charset
实例(请参阅email.charset
),设置,或None
。如果它是一个字符串,它将被转换为Charset
实例。如果字符集为None
,则charset
参数将从Content-Type否则修改)。任何其他将生成TypeError
。如果没有现有的MIME-Version头,那么将添加一个。如果没有现有的Content-Type标题,则会添加一个值text / plain。无论Content-Type头是否已存在,其
charset
参数将设置为charset.output_charset。如果charset.input_charset和charset.output_charset不同,有效负载将重新编码为output_charset。如果没有现有的Content-Transfer-Encoding头,那么如果需要,有效载荷将使用指定的Charset
进行传输编码,将被添加。如果Content-Transfer-Encoding头已经存在,则假定有效载荷已经使用内容传送编码正确编码,并且不被修改。
以下方法实现了类似映射的接口,用于访问消息的 RFC 2822头。注意,在这些方法和正常映射(即,映射)之间存在一些语义差异。字典)接口。例如,在字典中没有重复的键,但在这里可能有重复的邮件标题。此外,在字典中,对
keys()
返回的键没有保证顺序,但在Message
对象中,标题总是按照它们在原始消息,或者稍后添加到消息中。任何头删除,然后重新添加总是附加到头列表的末尾。这些语义差异是有意的,并且偏向于最大的方便。
注意,在所有情况下,消息中存在的任何包络头都不包括在映射接口中。
在从字节生成的模型中,任何(违反RFC)包含非ASCII字节的报头值将通过此接口检索时表示为
Header
对象,其字符集为未知-8位。-
__len__
()¶ 返回标头的总数,包括重复的总数。
-
__contains__
(name)¶ 如果消息对象具有名为name的字段,则返回true。匹配不区分大小写,名称不应包含结尾冒号。用于
in
操作符,例如:if 'message-id' in myMessage: print('Message-ID:', myMessage['message-id'])
-
__getitem__
(name)¶ 返回指定头字段的值。名称不应包含冒号字段分隔符。如果标头缺失,则返回
None
;从不引发KeyError
。请注意,如果命名字段在消息的标头中多次出现,则不确定将返回哪些字段值。使用
get_all()
方法获取所有现有命名标头的值。
-
__setitem__
(name, val)¶ 在字段名称名称和值val的邮件中添加标题。该字段将追加到消息的现有字段的末尾。
请注意,不会覆盖或删除任何具有相同名称的现有标题。如果您想要确保新标头是邮件中只有一个字段名为name的字段,请先删除该字段,例如。:
del msg['subject'] msg['subject'] = 'Python roolz!'
-
__delitem__
(name)¶ 从邮件标头中删除名称为name的所有字段。如果命名字段不存在于标题中,则不会引发异常。
-
keys
()¶ 返回所有邮件头字段名称的列表。
-
values
()¶ 返回所有消息的字段值的列表。
-
items
()¶ 返回包含所有消息的字段标头和值的2元组列表。
-
get
(name, failobj=None)¶ 返回指定头字段的值。这与
__getitem__()
相同,但如果指定的标头缺失(默认为None
),则返回可选的failobj。
以下是一些其他有用的方法:
-
get_all
(name, failobj=None)¶ 返回名为name的字段的所有值的列表。如果消息中没有这样的命名头,则返回failobj(默认为
None
)。
-
add_header
(_name, _value, **_params)¶ 扩展头设置。此方法类似于
__setitem__()
,除了可以提供附加头参数作为关键字参数。_name是要添加的头字段,_value是头的主值。对于关键字参数字典_params中的每个项目,将键作为参数名称,将下划线转换为破折号(因为破折号在Python标识符中是非法的)。通常,该参数将作为
key="value"
添加,除非该值为None
,在这种情况下将仅添加密钥。如果值包含非ASCII字符,则可以指定为(CHARSET, LANGUAGE, VALUE) t3格式的三元组>
,其中CHARSET
是用于对值进行编码的字符集的字符串,LANGUAGE
通常可以设置为None
或空字符串(有关其他可能性,请参见 RFC 2231),VALUE
是包含非ASCII代码点的字符串值。If a three tuple is not passed and the value contains non-ASCII characters, it is automatically encoded in RFC 2231 format using aCHARSET
ofutf-8
and aLANGUAGE
ofNone
.这里有一个例子:
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"
-
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 t4 >。
-
get_content_maintype
()¶ 返回邮件的主要内容类型。这是由
get_content_type()
返回的字符串的主类型部分。
-
get_content_subtype
()¶ 返回邮件的子内容类型。这是由
get_content_type()
返回的字符串的子类型部分。
-
get_default_type
()¶ 返回默认内容类型。大多数邮件的默认内容类型为text / plain,但作为multipart / digest容器的子部分的邮件除外。这样的子部分具有默认内容类型message / rfc822。
-
set_default_type
(ctype)¶ 设置默认内容类型。ctype应为text / plain或message / rfc822,但不强制执行。默认内容类型不存储在Content-Type标题中。
-
get_params
(failobj=None, header='content-type', unquote=True)¶ 以列表形式返回消息的Content-Type参数。返回列表的元素是2元组的键/值对,在
'='
符号上分割。'='
的左侧是键,右侧是值。如果参数中没有'='
符号,则该值为空字符串,否则该值如get_param()
中所述,如果可选,unquote是True
(默认值)。如果没有Content-Type标头,则可选的failobj是要返回的对象。可选的标头是要搜索的标头,而不是内容类型。
-
get_param
(param, failobj=None, header='content-type', unquote=True)¶ 将Content-Type头参数param的值作为字符串返回。如果消息没有Content-Type头,或者如果没有此类参数,则返回failobj(默认为
None
)。可选头(如果给出)指定要使用的消息头,而不是Content-Type。
参数键总是比较不区分大小写。返回值可以是字符串,如果参数为 RFC 2231编码,则返回3元组。当它是3元组时,值的元素为
(CHARSET, LANGUAGE, VALUE) t0 >。
请注意,CHARSET
和LANGUAGE
可以是None
,在这种情况下,您应该考虑VALUE
us-ascii
字符集。您通常可以忽略LANGUAGE
。If your application doesn’t care whether the parameter was encoded as in RFC 2231, you can collapse the parameter value by calling
email.utils.collapse_rfc2231_value()
, passing in the return value fromget_param()
. 当值是元组时,将返回一个适当解码的Unicode字符串,否则返回原始字符串。例如:rawparam = msg.get_param('foo') param = email.utils.collapse_rfc2231_value(rawparam)
In any case, the parameter value (either the returned string, or the
VALUE
item in the 3-tuple) is always unquoted, unless unquote is set toFalse
.
-
set_param
(param, value, header='Content-Type', requote=True, charset=None, language='', replace=False)¶ 在Content-Type标题中设置参数。如果参数已存在于标头中,则其值将替换为value。如果Content-Type头尚未为此消息定义,则它将设置为text / plain,新参数值将根据 RFC 2045。
Optional header specifies an alternative header to Content-Type, and all parameters will be quoted as necessary unless optional requote is
False
(the default isTrue
).如果指定了可选的字符集,则将根据 RFC 2231对参数进行编码。可选的语言指定RFC 2231语言,默认为空字符串。字符集和语言应为字符串。
如果replace是
False
(默认值),标题将移动到标题列表的末尾。如果replace是True
,则会正确更新标头。在版本3.4中已更改:
replace
添加了关键字。
-
del_param
(param, header='content-type', requote=True)¶ 从Content-Type标题中完全删除给定的参数。标题将重新写入到位,没有参数或其值。除非requote为
False
(默认值为True
),否则所有值都将被引用。可选头指定Content-Type的替代方法。
-
set_type
(type, header='Content-Type', requote=True)¶ 设置Content-Type头的主类型和子类型。类型必须是maintype / subtype形式的字符串,否则会引发
ValueError
。此方法替换Content-Type头,保留所有参数。如果requote是
False
,则保留现有标头的引号,否则参数将被引用(默认值)。可以在头参数中指定替代头。当Content-Type头设置时,还会添加一个MIME-Version头。
-
get_filename
(failobj=None)¶ 返回消息的Content-Disposition标头的
filename
参数的值。如果标头没有filename
参数,此方法将回到在Content-Type标头上寻找name
参数。如果没有找到,或者标头丢失,则返回failobj。返回的字符串将始终不按照email.utils.unquote()
引用。
-
get_boundary
(failobj=None)¶ 返回邮件Content-Type标头的
boundary
参数的值,如果标头缺失或没有,则返回failobjboundary
参数。返回的字符串将始终不按照email.utils.unquote()
引用。
-
set_boundary
(boundary)¶ 将Content-Type标头的
boundary
参数设为boundary。set_boundary()
将总是引用boundary。如果消息对象没有Content-Type头,则会引发HeaderParseError
。请注意,使用此方法与删除旧的Content-Type标头并通过
add_header()
添加一个新边界,因为set_boundary()
会保留标头列表中Content-Type标头的顺序。但是,不保留原始Content-Type标头中可能存在的任何连续行。
-
get_content_charset
(failobj=None)¶ 返回Content-Type标题的
charset
参数,强制为小写。如果没有Content-Type标头,或者该标头没有charset
参数,则返回failobj。请注意,此方法不同于
get_charset()
,它返回消息正文的默认编码的Charset
实例。
-
get_charsets
(failobj=None)¶ 返回包含消息中字符集名称的列表。如果消息是multipart,则列表将为有效内容中的每个子部分包含一个元素,否则将是长度为1的列表。
列表中的每个项目都将是一个字符串,它是所表示子部分的Content-Type标题中
charset
参数的值。但是,如果子部件没有Content-Type头,没有charset
参数,或者不是文本主MIME类型,在返回的列表中将是failobj。
-
get_content_disposition
()¶ 返回消息的Content-Disposition头的低位值(无参数)(如果有),或
None
。The possible values for this method are inline, attachment orNone
if the message follows RFC 2183.版本3.5中的新功能。
-
walk
()¶ walk()
方法是一个通用的生成器,可用于以深度优先遍历顺序遍历消息对象树的所有部分和子部分。在for
循环中,通常使用walk()
作为迭代器;每次迭代返回下一个子部分。下面是打印多部分消息结构的每个部分的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
iterates over the subparts of any part whereis_multipart()
returnsTrue
, even thoughmsg.get_content_maintype() == 'multipart'
may returnFalse
. 在我们的示例中,我们可以通过使用_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()
返回True
和walk
下降到子部分。
Message
对象还可以可选地包含两个实例属性,可以在生成MIME消息的纯文本时使用。-
preamble
¶ MIME文档的格式允许在标题后的空行和第一个多部分边界字符串之间有一些文本。通常,此文本在MIME感知邮件阅读器中永远不可见,因为它不属于标准MIME装甲。但是,在查看邮件的原始文本时,或在非MIME感知读取器中查看邮件时,此文本可能会变为可见。
前导码属性包含MIME文档的此前导装饰文本。当
Parser
发现标头之后但在第一个边界字符串之前的一些文本时,它将此文本分配给消息的前导码属性。当Generator
写出MIME消息的纯文本表示形式,并且它发现该消息具有前导码属性时,它将该文本写入标题和第一个边界。有关详细信息,请参见email.parser
和email.generator
。请注意,如果消息对象没有前导码,则前导码属性将为
None
。
-
defects
¶ 缺陷属性包含解析此消息时发现的所有问题的列表。有关可能的解析缺陷的详细说明,请参阅
email.errors
。
-