email.message.Message: 使用 compat32 API 來(lái)表示電子郵件消息?

Message 類(lèi)與 EmailMessage 類(lèi)非常相似,但沒(méi)有該類(lèi)所添加的方法,并且某些方法的默認行為也略有不同。 我們還在這里記錄了一些雖然被 EmailMessage 類(lèi)所支持但并不推薦的方法,除非你是在處理舊有代碼。

在其他情況下這兩個(gè)類(lèi)的理念和結構都是相同的。

本文檔描述了默認 (對于 Message) 策略 Compat32 之下的行為。 如果你要使用其他策略,你應當改用 EmailMessage 類(lèi)。

電子郵件消息由多個(gè) 標頭 和一個(gè) 載荷 組成。 標頭必須為 RFC 5322 風(fēng)格的名稱(chēng)和值,其中字典名和值由冒號分隔。 冒號不是字段名或字段值的組成部分。 載荷可以是簡(jiǎn)單的文本消息,或是二進(jìn)制對象,或是多個(gè)子消息的結構化序列,每個(gè)子消息都有自己的標頭集合和自己的載荷。 后一種類(lèi)型的載荷是由具有 multipart/*message/rfc822 等 MIME 類(lèi)型的消息來(lái)指明的。

Message 對象所提供了概念化模型是由標頭組成的有序字典,加上用于訪(fǎng)問(wèn)標頭中的特殊信息以及訪(fǎng)問(wèn)載荷的額外方法,以便能生成消息的序列化版本,并遞歸地遍歷對象樹(shù)。 請注意重復的標頭是受支持的,但必須使用特殊的方法來(lái)訪(fǎng)問(wèn)它們。

Message 偽字典以標頭名作為索引,標頭名必須為 ASCII 值。 字典的值為應當只包含 ASCII 字符的字符串;對于非 ASCII 輸入有一些特殊處理,但這并不總能產(chǎn)生正確的結果。 標頭以保留原大小寫(xiě)的形式存儲和返回,但字段名稱(chēng)匹配對大小寫(xiě)不敏感。 還可能會(huì )有一個(gè)單獨的封包標頭,也稱(chēng) Unix-From 標頭或 From_ 標頭。 載荷 對于簡(jiǎn)單消息對象的情況是一個(gè)字符串或字節串,對于 MIME 容器文檔的情況 (例如 multipart/*message/rfc822) 則是一個(gè) Message 對象。

以下是 Message 類(lèi)的方法:

class email.message.Message(policy=compat32)?

如果指定了 policy (它必須為 policy 類(lèi)的實(shí)例) 則使用它所設置的規則來(lái)更新和序列化消息的表示形式。 如果未設置 policy,則使用 compat32 策略,該策略會(huì )保持對 Python 3.2 版 email 包的向下兼容性。 更多信息請參閱 policy 文檔。

在 3.3 版更改: 增加了 policy 關(guān)鍵字參數。

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

以展平的字符串形式返回整個(gè)消息對象。 或可選的 unixfrom 為真值,返回的字符串會(huì )包括封包標頭。 unixfrom 的默認值是 False。 出于保持向下兼容性的原因,maxheaderlen 的默認值是 0,因此如果你想要不同的值你必須顯式地重載它(在策略中為 max_line_length 指定的值將被此方法忽略)。 policy 參數可被用于覆蓋從消息實(shí)例獲取的默認策略。 這可以用來(lái)對該方法所輸出的格式進(jìn)行一些控制,因為指定的 policy 將被傳遞給 Generator。

如果需要填充默認值以完成對字符串的轉換則展平消息可能觸發(fā)對 Message 的修改(例如,MIME 邊界可能會(huì )被生成或被修改)。

請注意此方法是出于便捷原因提供的,可能無(wú)法總是以你想要的方式格式化消息。 例如,在默認情況下它不會(huì )按 unix mbox 格式的要求對以 From 打頭的行執行調整。 為了獲得更高靈活性,請實(shí)例化一個(gè) Generator 實(shí)例并直接使用其 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 標準進(jìn)行編碼的二進(jìn)制數據,則這些不合規數據將被 unicode "unknown character" 碼位值所替代。 (另請參閱 as_bytes()BytesGenerator。)

在 3.4 版更改: 增加了 policy 關(guān)鍵字參數。

__str__()?

as_string() 等價(jià)。 這將讓 str(msg) 產(chǎn)生一個(gè)包含已格式化消息的字符號。

as_bytes(unixfrom=False, policy=None)?

以字節串對象的形式返回整個(gè)扁平化后的消息。 當可選的 unixfrom 為真值時(shí),返回的字符串會(huì )包括封包標頭。 unixfrom 的默認值為 False。 policy 參數可被用于重載從消息實(shí)例獲取的默認策略。 這可被用來(lái)控制該方法所產(chǎn)生的部分格式化效果,因為指定的 policy 將被傳遞給 BytesGenerator。

如果需要填充默認值以完成對字符串的轉換則展平消息可能觸發(fā)對 Message 的修改(例如,MIME 邊界可能會(huì )被生成或被修改)。

請注意此方法是出于便捷原因提供的,可能無(wú)法總是以你想要的方式格式化消息。 例如,在默認情況下它不會(huì )按 unix mbox 格式的要求對以 From 打頭的行執行調整。 為了獲得更高靈活性,請實(shí)例化一個(gè) BytesGenerator 實(shí)例并直接使用其 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() 等價(jià)。 這將讓 bytes(msg) 產(chǎn)生一個(gè)包含已格式化消息的字節串對象。

3.4 新版功能.

is_multipart()?

如果該消息的載荷是一個(gè)子 Message 對象列表則返回 True,否則返回 False。 當 is_multipart() 返回 False 時(shí),載荷應當是一個(gè)字符串對象(有可能是一個(gè) CTE 編碼的二進(jìn)制載荷)。 (請注意 is_multipart() 返回 True 并不意味著(zhù) "msg.get_content_maintype() == 'multipart'" 將返回 True。 例如,is_multipartMessage 類(lèi)型為 message/rfc822 時(shí)也將返回 True。)

set_unixfrom(unixfrom)?

將消息的封包標頭設為 unixfrom,這應當是一個(gè)字符串。

get_unixfrom()?

返回消息的信封頭。如果信封頭從未被設置過(guò),默認返回 None 。

attach(payload)?

將給定的 payload 添加到當前載荷中,當前載荷在該調用之前必須為 None 或是一個(gè) Message 對象列表。 在調用之后,此載荷將總是一個(gè) Message 對象列表。 如果你想將此載荷設為一個(gè)標量對象(如字符串),請改用 set_payload()。

這是一個(gè)過(guò)時(shí)的方法。 在 EmailMessage 類(lèi)上它的功能已被 set_content() 及相應的 makeadd 方法所替代。

get_payload(i=None, decode=False)?

返回當前的載荷,它在 is_multipart()True 時(shí)將是一個(gè) Message 對象列表,在 is_multipart()False 時(shí)則是一個(gè)字符串。 如果該載荷是一個(gè)列表且你修改了這個(gè)列表對象,那么你就是原地修改了消息的載荷。

傳入可選參數 i 時(shí),如果 is_multipart()True,get_payload() 將返回載荷從零開(kāi)始計數的第 i 個(gè)元素。 如果 i 小于 0 或大于等于載荷中的條目數則將引發(fā) IndexError。 如果載荷是一個(gè)字符串 (即 is_multipart()False) 且給出了 i,則會(huì )引發(fā) TypeError。

可選的 decode 是一個(gè)指明載荷是否應根據 Content-Transfer-Encoding 標頭被解碼的旗標。 當其值為 True 且消息沒(méi)有多個(gè)部分時(shí),如果此標頭值為 quoted-printablebase64 則載荷將被解碼。 如果使用了其他編碼格式,或者找不到 Content-Transfer-Encoding 標頭時(shí),載荷將被原樣返回(不編碼)。 在所有情況下返回值都是二進(jìn)制數據。 如果消息有多個(gè)部分且 decode 旗標為 True,則將返回 None。 如果載荷為 base64 但內容不完全正確(如缺少填充符、存在 base64 字母表以外的字符等),則將在消息的缺陷屬性中添加適當的缺陷值 (分別為 InvalidBase64PaddingDefectInvalidBase64CharactersDefect)。

decodeFalse (默認值) 時(shí)消息體會(huì )作為字符串返回而不解碼 Content-Transfer-Encoding。 但是,對于 Content-Transfer-Encoding 為 8bit 的情況,會(huì )嘗試使用 Content-Type 標頭指定的 charset 來(lái)解碼原始字節串,并使用 replace 錯誤處理程序。 如果未指定 charset,或者如果指定的 charset 未被 email 包所識別,則會(huì )使用默認的 ASCII 字符集來(lái)解碼消息體。

這是一個(gè)過(guò)時(shí)的方法。 在 EmailMessage 類(lèi)上它的功能已被 get_content()iter_parts() 方法所替代。

set_payload(payload, charset=None)?

將整個(gè)消息對象的載荷設為 payload。 客戶(hù)端要負責確保載荷的不變性。 可選的 charset 用于設置消息的默認字符集;詳情請參閱 set_charset()。

這是一個(gè)過(guò)時(shí)的方法。 在 EmailMessage 類(lèi)上它的功能已被 set_content() 方法所替代。

set_charset(charset)?

將載荷的字符集設為 charset,它可以是 Charset 實(shí)例 (參見(jiàn) email.charset)、字符集名稱(chēng)字符串或 None。 如果是字符串,它將被轉換為一個(gè) Charset 實(shí)例。 如果 charsetNone,charset 形參將從 Content-Type 標頭中被刪除(消息將不會(huì )進(jìn)行其他修改)。 任何其他值都將導致 TypeError。

如果 MIME-Version 標頭不存在則將被添加。 如果 Content-Type 標頭不存在,則將添加一個(gè)值為 text/plain 的該標頭。 無(wú)論 Content-Type 標頭是否已存在,其 charset 形參都將被設為 charset.output_charset。 如果 charset.input_charsetcharset.output_charset 不同,則載荷將被重編碼為 output_charset。 如果 Content-Transfer-Encoding 標頭不存在,則載荷將在必要時(shí)使用指定的 Charset 來(lái)轉換編碼,并將添加一個(gè)具有相應值的標頭。 如果 Content-Transfer-Encoding 標頭已存在,則會(huì )假定載荷已使用該 Content-Transfer-Encoding 進(jìn)行正確編碼并不會(huì )再被修改。

這是一個(gè)過(guò)時(shí)的方法。 在 EmailMessage 類(lèi)上它的功能已被 email.emailmessage.EmailMessage.set_content() 方法的 charset 形參所替代。

get_charset()?

返回與消息的載荷相關(guān)聯(lián)的 Charset 實(shí)例。

這是一個(gè)過(guò)時(shí)的方法。 在 EmailMessage 類(lèi)上它將總是返回 None。

以下方法實(shí)現了用于訪(fǎng)問(wèn)消息的 RFC 2822 標頭的類(lèi)映射接口。 請注意這些方法和普通映射(例如字典)接口之間存在一些語(yǔ)義上的不同。 舉例來(lái)說(shuō),在一個(gè)字典中不能有重復的鍵,但消息標頭則可能有重復。 并且,在字典中由 keys() 返回的鍵的順序是沒(méi)有保證的,但在 Message 對象中,標頭總是會(huì )按它們在原始消息中的出現或后繼加入順序返回。 任何已刪除再重新加入的標頭總是會(huì )添加到標頭列表的末尾。

這些語(yǔ)義上的差異是有意為之且其目的是為了提供最大的便利性。

請注意在任何情況下,消息當中的任何封包標頭都不會(huì )包含在映射接口當中。

在由字節串生成的模型中,任何包含非 ASCII 字節數據(違反 RFC)的標頭值當通過(guò)此接口來(lái)獲取時(shí),將被表示為使用 unknown-8bit 字符集的 Header 對象。

__len__()?

返回標頭的總數,包括重復項。

__contains__(name)?

如果消息對象中有一個(gè)名為 name 的字段則返回 True。 匹配操作對大小寫(xiě)不敏感并且 name 不應包括末尾的冒號。 用于 in 運算符,例如:

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

返回指定名稱(chēng)標頭字段的值。 name 不應包括作為字段分隔符的冒號。 如果標頭未找到,則返回 None;KeyError 永遠不會(huì )被引發(fā)。

請注意如果指定名稱(chēng)的字段在消息標頭中多次出現,具體將返回哪個(gè)字段值是未定義的。 請使用 get_all() 方法來(lái)獲取所有指定名稱(chēng)標頭的值。

__setitem__(name, val)?

將具有字段名 name 和值 val 的標頭添加到消息中。 字段會(huì )被添加到消息的現有字段的末尾。

請注意,這個(gè)方法 既不會(huì ) 覆蓋 也不會(huì ) 刪除任何字段名重名的已有字段。如果你確實(shí)想保證新字段是整個(gè)信息頭當中唯一擁有 name 字段名的字段,你需要先把舊字段刪除。例如:

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

刪除信息頭當中字段名匹配 name 的所有字段。如果匹配指定名稱(chēng)的字段沒(méi)有找到,也不會(huì )拋出任何異常。

keys()?

以列表形式返回消息頭中所有的字段名。

values()?

以列表形式返回消息頭中所有的字段值。

items()?

以二元元組的列表形式返回消息頭中所有的字段名和字段值。

get(name, failobj=None)?

返回指定名稱(chēng)標頭字段的值。 這與 __getitem__() 是一樣的,不同之處在于如果指定名稱(chēng)標頭未找到則會(huì )返回可選的 failobj (默認為 None)。

以下是一些有用的附加方法:

get_all(name, failobj=None)?

返回字段名為 name 的所有字段值的列表。如果信息內不存在匹配的字段,返回 failobj (其默認值為 None )。

add_header(_name, _value, **_params)?

高級頭字段設定。這個(gè)方法與 __setitem__() 類(lèi)似,不過(guò)你可以使用關(guān)鍵字參數為字段提供附加參數。 _name 是字段名, _value 是字段 值。

對于關(guān)鍵字參數字典 _params 中的每一項,其鍵會(huì )被當作形參名,并執行下劃線(xiàn)和連字符間的轉換(因為連字符不是合法的 Python 標識符)。 通常,形參將以 key="value" 的形式添加,除非值為 None,在這種情況下將只添加鍵。 如果值包含非 ASCII 字符,可將其指定為格式為 (CHARSET, LANGUAGE, VALUE) 的三元組,其中 CHARSET 為要用來(lái)編碼值的字符集名稱(chēng)字符串,LANGUAGE 通??稍O為 None 或空字符串(請參閱 RFC 2231 了解其他可能的取值),而 VALUE 為包含非 ASCII 碼位的字符串值。 如果不是傳入一個(gè)三元組且值包含非 ASCII 字符,則會(huì )自動(dòng)以 RFC 2231 格式使用 CHARSETutf-8LANGUAGENone 對其進(jìn)行編碼。

以下是為示例代碼:

msg.add_header('Content-Disposition', 'attachment', filename='bud.gif')

會(huì )添加一個(gè)形如下文的頭字段:

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)?

替換一個(gè)標頭。 將替換在匹配 _name 的消息中找到的第一個(gè)標頭,標頭順序和字段名大小寫(xiě)保持不變。 如果未找到匹配的標頭,則會(huì )引發(fā) KeyError。

get_content_type()?

返回消息的內容類(lèi)型。 返回的字符串會(huì )強制轉換為 maintype/subtype 的全小寫(xiě)形式。 如果消息中沒(méi)有 Content-Type 標頭則將返回由 get_default_type() 給出的默認類(lèi)型。 因為根據 RFC 2045,消息總是要有一個(gè)默認類(lèi)型,所以 get_content_type() 將總是返回一個(gè)值。

RFC 2045 將消息的默認類(lèi)型定義為 text/plain,除非它是出現在 multipart/digest 容器內,在這種情況下其類(lèi)型應為 message/rfc822。 如果 Content-Type 標頭指定了無(wú)效的類(lèi)型,RFC 2045 規定其默認類(lèi)型應為 text/plain。

get_content_maintype()?

返回信息的主要內容類(lèi)型。準確來(lái)說(shuō),此方法返回的是 get_content_type() 方法所返回的形如 maintype/subtype 的字符串當中的 maintype 部分。

get_content_subtype()?

返回信息的子內容類(lèi)型。準確來(lái)說(shuō),此方法返回的是 get_content_type() 方法所返回的形如 maintype/subtype 的字符串當中的 subtype 部分。

get_default_type()?

返回默認的內容類(lèi)型。絕大多數的信息,其默認內容類(lèi)型都是 text/plain 。作為 multipart/digest 容器內子部分的信息除外,它們的默認內容類(lèi)型是 message/rfc822 。

set_default_type(ctype)?

設置默認的內容類(lèi)型。 ctype 應當為 text/plain 或者 message/rfc822,盡管這并非強制。 默認的內容類(lèi)型不會(huì )存儲在 Content-Type 標頭中。

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

將消息的 Content-Type 形參作為列表返回。 所返回列表的元素為以 '=' 號拆分出的鍵/值對 2 元組。 '=' 左側的為鍵,右側的為值。 如果形參值中沒(méi)有 '=' 號,否則該將值如 get_param() 描述并且在可選 unquoteTrue (默認值) 時(shí)會(huì )被取消轉義。

可選的 failobj 是在沒(méi)有 Content-Type 標頭時(shí)要返回的對象。 可選的 header 是要替代 Content-Type 被搜索的標頭。

這是一個(gè)過(guò)時(shí)的方法。 在 EmailMessage 類(lèi)上它的功能已被標頭訪(fǎng)問(wèn)方法所返回的單獨標頭對象的 params 特征屬性所替代。

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

Content-Type 標頭的形參 param 作為字符串返回。 如果消息沒(méi)有 Content-Type 標頭或者沒(méi)有這樣的形參,則返回 failobj (默認為 None)。

如果給出可選的 header,它會(huì )指定要替代 Content-Type 來(lái)使用的消息標頭。

形參的鍵總是以大小寫(xiě)不敏感的方式來(lái)比較的。 返回值可以是一個(gè)字符串,或者如果形參以 RFC 2231 編碼則是一個(gè) 3 元組。 當為 3 元組時(shí),值中的元素采用 (CHARSET, LANGUAGE, VALUE) 的形式。 請注意 CHARSETLANGUAGE 都可以為 None,在此情況下你應當將 VALUE 當作以 us-ascii 字符集來(lái)編碼。 你可以總是忽略 LANGUAGE。

如果你的應用不關(guān)心形參是否以 RFC 2231 來(lái)編碼,你可以通過(guò)調用 email.utils.collapse_rfc2231_value() 來(lái)展平形參值,傳入來(lái)自 get_param() 的返回值。 當值為元組時(shí)這將返回一個(gè)經(jīng)適當編碼的 Unicode 字符串,否則返回未經(jīng)轉換的原字符串。 例如:

rawparam = msg.get_param('foo')
param = email.utils.collapse_rfc2231_value(rawparam)

無(wú)論在哪種情況下,形參值(或為返回的字符串,或為 3 元組形式的 VALUE 條目)總是未經(jīng)轉換的,除非 unquote 被設為 False。

這是一個(gè)過(guò)時(shí)的方法。 在 EmailMessage 類(lèi)上它的功能已被標頭訪(fǎng)問(wèn)方法所返回的單獨標頭對象的 params 特征屬性所替代。

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

Content-Type 標頭中設置一個(gè)形參。 如果該形參已存在于標頭中,它的值將被替換為 value。 如果此消息還未定義 Content-Type 標頭,它將被設為 text/plain 且新的形參值將按 RFC 2045 的要求添加。

可選的 header 指定一個(gè) Content-Type 的替代標頭,并且所有形參將根據需要被轉換,除非可選的 requoteFalse (默認為 True)。

如果指定了可選的 charset,形參將按照 RFC 2231 來(lái)編碼。 可選的 language 指定了 RFC 2231 的語(yǔ)言,默認為空字符串。 charsetlanguage 都應為字符串。

如果 replaceFalse (默認值),該頭字段會(huì )被移動(dòng)到所有頭字段列表的末尾。如果 replaceTrue ,字段會(huì )被原地更新。

在 3.4 版更改: 添加了 replace 關(guān)鍵字。

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

Content-Type 標頭中完全移除給定的形參。 標頭將被原地重寫(xiě)并不帶該形參或它的值。 所有的值將根據需要被轉換,除非 requoteFalse (默認為 True)。 可選的 header 指定 Content-Type 的一個(gè)替代項。

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

設置 Content-Type 標頭的主類(lèi)型和子類(lèi)型。 type 必須為 maintype/subtype 形式的字符串,否則會(huì )引發(fā) ValueError。

此方法可替換 Content-Type 標頭,并保持所有形參不變。 如果 requoteFalse,這會(huì )保持原有標頭引用轉換不變,否則形參將被引用轉換(默認行為)。

可以在 header 參數中指定一個(gè)替代標頭。 當 Content-Type 標頭被設置時(shí)也會(huì )添加一個(gè) MIME-Version 標頭。

這是一個(gè)過(guò)時(shí)的方法。 在 EmailMessage 類(lèi)上它的功能已被 make_add_ 方法所替代。

get_filename(failobj=None)?

返回信息頭當中 Content-Disposition 字段當中名為 filename 的參數值。如果該字段當中沒(méi)有此參數,該方法會(huì )退而尋找 Content-Type 字段當中的 name 參數值。如果這個(gè)也沒(méi)有找到,或者這些個(gè)字段壓根就不存在,返回 failobj 。返回的字符串永遠按照 email.utils.unquote() 方法去除引號。

get_boundary(failobj=None)?

返回信息頭當中 Content-Type 字段當中名為 boundary 的參數值。如果字段當中沒(méi)有此參數,或者這些個(gè)字段壓根就不存在,返回 failobj 。返回的字符串永遠按照 email.utils.unquote() 方法去除引號。

set_boundary(boundary)?

Content-Type 頭字段的 boundary 參數設置為 boundary 。 set_boundary() 方法永遠都會(huì )在必要的時(shí)候為 boundary 添加引號。如果信息對象中沒(méi)有 Content-Type 頭字段,拋出 HeaderParseError 異常。

請注意使用這個(gè)方法與刪除舊的 Content-Type 標頭并通過(guò) add_header() 添加一個(gè)帶有新邊界的新標頭有細微的差異,因為 set_boundary() 會(huì )保留 Content-Type 標頭在原標頭列表中的順序。 但是,它 不會(huì ) 保留原 Content-Type 標頭中可能存在的任何連續的行。

get_content_charset(failobj=None)?

返回 Content-Type 頭字段中的 charset 參數,強制小寫(xiě)。如果字段當中沒(méi)有此參數,或者這個(gè)字段壓根不存在,返回 failobj 。

請注意此方法不同于 get_charset(),后者會(huì )返回 Charset 實(shí)例作為消息體的默認編碼格式。

get_charsets(failobj=None)?

返回一個(gè)包含了信息內所有字符集名字的列表。 如果信息是 multipart 類(lèi)型的,那么列表當中的每一項都對應其載荷的子部分的字符集名字。 否則,該列表是一個(gè)長(cháng)度為 1 的列表。

列表中的每一項都是字符串,它們是其所表示的子部分的 Content-Type 標頭中 charset 形參的值。 但是,如果該子部分沒(méi)有 Content-Type 標頭,或沒(méi)有 charset 形參,或者主 MIME 類(lèi)型不是 text,則所返回列表中的對應項將為 failobj。

get_content_disposition()?

如果信息的 Content-Disposition 頭字段存在,返回其字段值;否則返回 None 。返回的值均為小寫(xiě),不包含參數。如果信息遵循 RFC 2183 標準,則此方法的返回值只可能在 inline 、 attachmentNone 之間選擇。

3.5 新版功能.

walk()?

walk() 方法是一個(gè)多功能生成器。它可以被用來(lái)以深度優(yōu)先順序遍歷信息對象樹(shù)的所有部分和子部分。一般而言, walk() 會(huì )被用作 for 循環(huán)的迭代器,每一次迭代都返回其下一個(gè)子部分。

以下例子會(huì )打印出一封具有多部分結構之信息的每個(gè)部分的 MIME 類(lèi)型。

>>>
>>> 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 會(huì )遍歷所有 is_multipart() 方法返回 True 的部分之子部分,哪怕 msg.get_content_maintype() == 'multipart' 返回的是 False 。使用 _structure 除錯幫助函數可以幫助我們在下面這個(gè)例子當中看清楚這一點(diǎn):

>>>
>>> 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 也深入進(jìn)這些子部分中。

Message 對象也可以包含兩個(gè)可選的實(shí)例屬性,它們可被用于生成純文本的 MIME 消息。

preamble?

MIME 文檔格式在標頭之后的空白行以及第一個(gè)多部分的分界字符串之間允許添加一些文本, 通常,此文本在支持 MIME 的郵件閱讀器中永遠不可見(jiàn),因為它處在標準 MIME 保護范圍之外。 但是,當查看消息的原始文本,或當在不支持 MIME 的閱讀器中查看消息時(shí),此文本會(huì )變得可見(jiàn)。

preamble 屬性包含 MIME 文檔開(kāi)頭部分的這些處于保護范圍之外的文本。 當 Parser 在標頭之后及第一個(gè)分界字符串之前發(fā)現一些文本時(shí),它會(huì )將這些文本賦值給消息的 preamble 屬性。 當 Generator 寫(xiě)出 MIME 消息的純文本表示形式時(shí),如果它發(fā)現消息具有 preamble 屬性,它將在標頭及第一個(gè)分界之間區域寫(xiě)出這些文本。 請參閱 email.parseremail.generator 了解更多細節。

請注意如果消息對象沒(méi)有前導文本,則 preamble 屬性將為 None。

epilogue?

epilogue 屬性的作用方式與 preamble 屬性相同,區別在于它包含出現于最后一個(gè)分界與消息結尾之間的文本。

你不需要將 epilogue 設為空字符串以便讓 Generator 在文件末尾打印一個(gè)換行符。

defects?

defects 屬性包含在解析消息時(shí)發(fā)現的所有問(wèn)題的列表。 請參閱 email.errors 了解可能的解析缺陷的詳細描述。