email.generator
:生成 MIME 文件¶
最常見的任務之一是生成由訊息物件結構所表示的電子郵件訊息的扁平化(序列化)版本。如果你想要透過 smtplib.SMTP.sendmail()
傳送訊息,或者在控制檯上列印訊息,就需要這樣做。將一個訊息物件結構並生成其序列化表示形式正是生成器類的工作。
與 email.parser
模組一樣,你不僅限於使用捆綁的生成器;你也可以自己從頭編寫一個。但是,捆綁的生成器知道如何以符合標準的方式生成大多數電子郵件,應能很好地處理 MIME 和非 MIME 電子郵件訊息,並且其設計使得面向位元組的解析和生成操作是互逆的,前提是兩者使用相同的非轉換 policy
。也就是說,透過 BytesParser
類解析序列化的位元組流,然後使用 BytesGenerator
重新生成序列化的位元組流,應能產生與輸入完全相同的輸出 [1]。(另一方面,在透過程式構建的 EmailMessage
上使用生成器,可能會因為填充預設值而導致 EmailMessage
物件發生改變。)
可使用 Generator
類將訊息扁平化為文字(而非二進位制)的序列化表示,但由於 Unicode 無法直接表示二進位制資料,訊息必須轉換為只包含 ASCII 字元的內容,這透過使用標準的電子郵件 RFC 內容傳輸編碼技術,來為那些“非 8 位純淨”的通道傳輸電子郵件進行編碼。
為了支援對 SMIME 簽名的訊息進行可重現的處理,Generator
對於型別為 multipart/signed
的訊息部分及其所有子部分,會停用標頭摺疊。
- class email.generator.BytesGenerator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)¶
返回一個
BytesGenerator
物件,該物件會將提供給flatten()
方法的任何訊息,或提供給write()
方法的任何經過 surrogateescape 編碼的文字,寫入到 檔案類物件 *outfp* 中。 *outfp* 必須支援一個接受二進位制資料的write
方法。如果可選引數 *mangle_from_* 為
True
,則在正文中任何以確切字串"From "
(即From
後跟一個空格)開頭的行前面加上一個>
字元。*mangle_from_* 預設為 *policy* 的mangle_from_
設定值(對於compat32
策略,該值為True
,對於所有其他策略則為False
)。 *mangle_from_* 旨在用於訊息以 Unix mbox 格式儲存的情況(參見mailbox
和 WHY THE CONTENT-LENGTH FORMAT IS BAD)。如果 *maxheaderlen* 不為
None
,則重新摺疊任何長度超過 *maxheaderlen* 的標頭行;如果為0
,則不重新換行任何標頭。如果 *maxheaderlen* 為None
(預設值),則根據 *policy* 設定來換行標頭和其他訊息行。如果指定了 *policy*,則使用該策略來控制訊息生成。如果 *policy* 為
None
(預設值),則使用傳遞給flatten
的Message
或EmailMessage
物件關聯的策略來控制訊息生成。有關 *policy* 控制內容的詳細資訊,請參閱email.policy
。在 3.2 版本加入。
在 3.3 版本發生變更: 添加了 *policy* 關鍵字。
在 3.6 版本發生變更: *mangle_from_* 和 *maxheaderlen* 引數的預設行為將遵循策略。
- flatten(msg, unixfrom=False, linesep=None)¶
將以 *msg* 為根的訊息物件結構的文字表示列印到建立
BytesGenerator
例項時指定的輸出檔案。如果
policy
選項cte_type
是8bit
(預設值),則將原始已解析訊息中未被修改的任何標頭複製到輸出中,並保留高位設定的位元組與原始訊息一致,同時保留任何正文部分的非 ASCII Content-Transfer-Encoding。如果cte_type
是7bit
,則根據需要使用與 ASCII 相容的 Content-Transfer-Encoding 轉換高位設定的位元組。也就是說,將具有非 ASCII Content-Transfer-Encoding(Content-Transfer-Encoding: 8bit)的部分轉換為與 ASCII 相容的 Content-Transfer-Encoding,並使用 MIMEunknown-8bit
字元集對標頭中不符合 RFC 的非 ASCII 位元組進行編碼,從而使其符合 RFC 標準。如果 *unixfrom* 為
True
,則在根訊息物件的第一個 RFC 5322 標頭之前列印 Unix 郵箱格式使用的信封頭分隔符(見mailbox
)。如果根物件沒有信封頭,則建立一個標準的信封頭。預設值為False
。請注意,對於子部分,從不列印信封頭。如果 *linesep* 不為
None
,則將其用作扁平化訊息所有行之間的分隔符。如果 *linesep* 為None
(預設值),則使用 *policy* 中指定的值。
- clone(fp)¶
返回此
BytesGenerator
例項的一個獨立克隆,其選項設定完全相同,並將 *fp* 作為新的 *outfp*。
- write(s)¶
使用
ASCII
編解碼器和surrogateescape
錯誤處理程式對 *s* 進行編碼,並將其傳遞給傳入BytesGenerator
建構函式的 *outfp* 的 *write* 方法。
為了方便起見,EmailMessage
提供了 as_bytes()
和 bytes(aMessage)
(也即 __bytes__()
) 方法,這簡化了訊息物件的序列化二進位制表示的生成。更多詳情請參閱 email.message
。
由於字串無法表示二進位制資料,Generator
類必須將其扁平化的任何訊息中的所有二進位制資料轉換為 ASCII 相容格式,方法是將其轉換為 ASCII 相容的 Content-Transfer-Encoding。用電子郵件 RFC 的術語來說,可以認為 Generator
是序列化到一個“非 8 位純淨”的 I/O 流。換句話說,大多數應用程式會希望使用 BytesGenerator
,而不是 Generator
。
- class email.generator.Generator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)¶
返回一個
Generator
物件,該物件會將提供給flatten()
方法的任何訊息,或提供給write()
方法的任何文字,寫入到 檔案類物件 *outfp* 中。 *outfp* 必須支援一個接受字串資料的write
方法。如果可選引數 *mangle_from_* 為
True
,則在正文中任何以確切字串"From "
(即From
後跟一個空格)開頭的行前面加上一個>
字元。*mangle_from_* 預設為 *policy* 的mangle_from_
設定值(對於compat32
策略,該值為True
,對於所有其他策略則為False
)。 *mangle_from_* 旨在用於訊息以 Unix mbox 格式儲存的情況(參見mailbox
和 WHY THE CONTENT-LENGTH FORMAT IS BAD)。如果 *maxheaderlen* 不為
None
,則重新摺疊任何長度超過 *maxheaderlen* 的標頭行;如果為0
,則不重新換行任何標頭。如果 *maxheaderlen* 為None
(預設值),則根據 *policy* 設定來換行標頭和其他訊息行。如果指定了 *policy*,則使用該策略來控制訊息生成。如果 *policy* 為
None
(預設值),則使用傳遞給flatten
的Message
或EmailMessage
物件關聯的策略來控制訊息生成。有關 *policy* 控制內容的詳細資訊,請參閱email.policy
。在 3.3 版本發生變更: 添加了 *policy* 關鍵字。
在 3.6 版本發生變更: *mangle_from_* 和 *maxheaderlen* 引數的預設行為將遵循策略。
- flatten(msg, unixfrom=False, linesep=None)¶
將以 *msg* 為根的訊息物件結構的文字表示列印到建立
Generator
例項時指定的輸出檔案。如果
policy
選項cte_type
是8bit
,則生成訊息時會如同該選項被設定為7bit
一樣處理。(這是必需的,因為字串無法表示非 ASCII 位元組。)根據需要使用與 ASCII 相容的 Content-Transfer-Encoding 轉換高位設定的位元組。也就是說,將具有非 ASCII Content-Transfer-Encoding(Content-Transfer-Encoding: 8bit)的部分轉換為與 ASCII 相容的 Content-Transfer-Encoding,並使用 MIMEunknown-8bit
字元集對標頭中不符合 RFC 的非 ASCII 位元組進行編碼,從而使其符合 RFC 標準。如果 *unixfrom* 為
True
,則在根訊息物件的第一個 RFC 5322 標頭之前列印 Unix 郵箱格式使用的信封頭分隔符(見mailbox
)。如果根物件沒有信封頭,則建立一個標準的信封頭。預設值為False
。請注意,對於子部分,從不列印信封頭。如果 *linesep* 不為
None
,則將其用作扁平化訊息所有行之間的分隔符。如果 *linesep* 為None
(預設值),則使用 *policy* 中指定的值。在 3.2 版本發生變更: 增加了對重新編碼
8bit
訊息正文的支援,以及 *linesep* 引數。
為了方便起見,EmailMessage
提供了 as_string()
和 str(aMessage)
(也即 __str__()
) 方法,這簡化了訊息物件的格式化字串表示的生成。更多詳情請參閱 email.message
。
email.generator
模組還提供了一個派生類 DecodedGenerator
,它類似於 Generator
基類,不同之處在於非 text 部分不會被序列化,而是在輸出流中用一個根據部分資訊填充的模板派生出的字串來表示。
- class email.generator.DecodedGenerator(outfp, mangle_from_=None, maxheaderlen=None, fmt=None, *, policy=None)¶
行為與
Generator
類似,不同之處在於,對於傳遞給Generator.flatten()
的訊息的任何子部分,如果子部分的主型別是 text,則列印該子部分的解碼後的有效負載;如果主型別不是 text,則不列印它,而是使用該部分的資訊填充字串 *fmt*,並列印填充後的結果字串。要填充 *fmt*,執行
fmt % part_info
,其中part_info
是一個由以下鍵和值組成的字典:type
– 非 text 部分的完整 MIME 型別maintype
– 非 text 部分的主 MIME 型別subtype
– 非 text 部分的子 MIME 型別filename
– 非 text 部分的檔名description
– 與非 text 部分關聯的描述encoding
– 非 text 部分的內容傳輸編碼
如果 *fmt* 為
None
,則使用以下預設的 *fmt*“[Non-text (%(type)s) part of message omitted, filename %(filename)s]”
可選的 *_mangle_from_* 和 *maxheaderlen* 與
Generator
基類中的相同。
腳註