email.header: 國際化標(biāo)頭?

源代碼: Lib/email/header.py


此模塊是舊式 (Compat32) email API 的一部分。 在當(dāng)前的 API 中標(biāo)頭的編碼和解碼是由 EmailMessage 類的字典型 API 來透明地處理的。 除了在舊有代碼中使用,此模塊在需要完全控制當(dāng)編碼標(biāo)頭時(shí)所使用的字符集時(shí)也很有用處。

本節(jié)中的其余文本是此模塊的原始文檔。

RFC 2822 是描述電子郵件消息格式的基礎(chǔ)標(biāo)準(zhǔn)。 它派生自更早的 RFC 822 標(biāo)準(zhǔn),該標(biāo)準(zhǔn)在大多數(shù)電子郵件僅由 ASCII 字符組成時(shí)已被廣泛使用。 RFC 2822 所描述的規(guī)范假定電子郵件都只包含 7 位 ASCII 字符。

當(dāng)然,隨著電子郵件在全球部署,它已經(jīng)變得國際化了,例如電子郵件消息中現(xiàn)在可以使用特定語言的專屬字符集。 這個(gè)基礎(chǔ)標(biāo)準(zhǔn)仍然要求電子郵件消息只使用 7 位 ASCII 字符來進(jìn)行傳輸,為此編寫了大量 RFC 來描述如何將包含非 ASCII 字符的電子郵件編碼為符合 RFC 2822 的格式。 這些 RFC 包括 RFC 2045, RFC 2046, RFC 2047RFC 2231email 包在其 email.headeremail.charset 模塊中支持了這些標(biāo)準(zhǔn)。

如果你想在你的電子郵件標(biāo)頭中包括非 ASCII 字符,比如說是在 SubjectTo 字段中,你應(yīng)當(dāng)使用 Header 類并將 Message 對(duì)象中的字段賦值為 Header 的實(shí)例而不是使用字符串作為字段值。 請(qǐng)從 email.header 模塊導(dǎo)入 Header 類。 例如:

>>>
>>> from email.message import Message
>>> from email.header import Header
>>> msg = Message()
>>> h = Header('p\xf6stal', 'iso-8859-1')
>>> msg['Subject'] = h
>>> msg.as_string()
'Subject: =?iso-8859-1?q?p=F6stal?=\n\n'

是否注意到這里我們是如何希望 Subject 字段包含非 ASCII 字符的? 我們通過創(chuàng)建一個(gè) Header 實(shí)例并傳入字節(jié)串編碼所用的字符集來做到這一點(diǎn)。 當(dāng)后續(xù)的 Message 實(shí)例被展平時(shí),Subject 字段會(huì)正確地按 RFC 2047 來編碼。 可感知 MIME 的電子郵件閱讀器將會(huì)使用嵌入的 ISO-8859-1 字符來顯示此標(biāo)頭。

以下是 Header 類描述:

class email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')?

創(chuàng)建符合 MIME 要求的標(biāo)頭,其中可包含不同字符集的字符串。

可選的 s 是初始標(biāo)頭值。 如果為 None (默認(rèn)值),則表示初始標(biāo)頭值未設(shè)置。 你可以在稍后使用 append() 方法調(diào)用向標(biāo)頭添加新值。 s 可以是 bytesstr 的實(shí)例,注意參閱 append() 文檔了解相關(guān)語義。

可選的 charset 用于兩種目的:它的含義與 append() 方法的 charset 參數(shù)相同。 它還會(huì)為所有省略了 charset 參數(shù)的后續(xù) append() 調(diào)用設(shè)置默認(rèn)字符集。 如果 charset 在構(gòu)造器中未提供(默認(rèn)設(shè)置),則會(huì)將 us-ascii 字符集用作 s 的初始字符集以及后續(xù) append() 調(diào)用的默認(rèn)字符集。

通過 maxlinelen 可以顯式指定最大行長度。 要將第一行拆分為更短的值 (以適應(yīng)未被包括在to account for the field header which isn't included in s 中的字段標(biāo)頭,例如 Subject),則將字段名稱作為 header_name 傳入。 maxlinelen 默認(rèn)值為 76,而 header_name 默認(rèn)值為 None,表示不考慮拆分超長標(biāo)頭的第一行。

可選的 continuation_ws 必須為符合 RFC 2822 的折疊用空白符,通常是空格符或硬制表符。 這個(gè)字符將被加綴至連續(xù)行的開頭。 continuation_ws 默認(rèn)為一個(gè)空格符。

可選的 errors 會(huì)被直接傳遞給 append() 方法。

append(s, charset=None, errors='strict')?

將字符串 s 添加到 MIME 標(biāo)頭。

如果給出可選的 charset,它應(yīng)當(dāng)是一個(gè) Charset 實(shí)例 (參見 email.charset) 或字符集名稱,該參數(shù)將被轉(zhuǎn)換為一個(gè) Charset 實(shí)例。 如果為 None (默認(rèn)值) 則表示會(huì)使用構(gòu)造器中給出的 charset

s 可以是 bytesstr 的實(shí)例。 如果它是 bytes 的實(shí)例,則 charset 為該字節(jié)串的編碼格式,如果字節(jié)串無法用該字符集來解碼則將引發(fā) UnicodeError

如果 sstr 的實(shí)例,則 charset 是用來指定字符串中字符字符集的提示。

在這兩種情況下,當(dāng)使用 RFC 2047 規(guī)則產(chǎn)生符合 RFC 2822 的標(biāo)頭時(shí),將使用指定字符集的輸出編解碼器來編碼字符串。 如果字符串無法使用該輸出編解碼器來編碼,則將引發(fā) UnicodeError。

可選的 errors 會(huì)在 s 為字節(jié)串時(shí)被作為 errors 參數(shù)傳遞給 decode 調(diào)用。

encode(splitchars=';, \t', maxlinelen=None, linesep='\n')?

將消息標(biāo)頭編碼為符合 RFC 的格式,可能會(huì)對(duì)過長的行采取折行并將非 ASCII 部分以 base64 或 quoted-printable 編碼格式進(jìn)行封裝。

可選的 splitchars 是一個(gè)字符串,其中包含應(yīng)在正常的標(biāo)頭折行處理期間由拆分算法賦予額外權(quán)重的字符。 這是對(duì)于 RFC 2822 中 '更高層級(jí)語法拆分' 的很粗略的支持:在拆分期間會(huì)首選在 splitchar 之前的拆分點(diǎn),字符的優(yōu)先級(jí)是基于它們在字符串中的出現(xiàn)順序。 字符串中可包含空格和制表符以指明當(dāng)其他拆分字符未在被拆分行中出現(xiàn)時(shí)是否要將某個(gè)字符作為優(yōu)先于另一個(gè)字符的首選拆分點(diǎn)。 拆分字符不會(huì)影響以 RFC 2047 編碼的行。

如果給出 maxlinelen,它將覆蓋實(shí)例的最大行長度值。

linesep 指定用來分隔已折疊標(biāo)頭行的字符。 它默認(rèn)為 Python 應(yīng)用程序代碼中最常用的值 (\n),但也可以指定為 \r\n 以便產(chǎn)生帶有符合 RFC 的行分隔符的標(biāo)頭。

在 3.2 版更改: 增加了 linesep 參數(shù)。

Header 類還提供了一些方法以支持標(biāo)準(zhǔn)運(yùn)算符和內(nèi)置函數(shù)。

__str__()?

以字符串形式返回 Header 的近似表示,使用不受限制的行長度。 所有部分都會(huì)使用指定編碼格式轉(zhuǎn)換為 unicode 并適當(dāng)?shù)剡B接起來。 任何帶有 'unknown-8bit' 字符集的部分都會(huì)使用 'replace' 錯(cuò)誤處理程序解碼為 ASCII。

在 3.2 版更改: 增加對(duì) 'unknown-8bit' 字符集的處理。

__eq__(other)?

這個(gè)方法允許你對(duì)兩個(gè) Header 實(shí)例進(jìn)行相等比較。

__ne__(other)?

這個(gè)方法允許你對(duì)兩個(gè) Header 實(shí)例進(jìn)行不等比較。

email.header 模塊還提供了下列便捷函數(shù)。

email.header.decode_header(header)?

在不轉(zhuǎn)換字符集的情況下對(duì)消息標(biāo)頭值進(jìn)行解碼。 header 為標(biāo)頭值。

這個(gè)函數(shù)返回一個(gè) (decoded_string, charset) 對(duì)的列表,其中包含標(biāo)頭的每個(gè)已解碼部分。 對(duì)于標(biāo)頭的未編碼部分 charsetNone,在其他情況下則為一個(gè)包含已編碼字符串中所指定字符集名稱的小寫字符串。

以下是為示例代碼:

>>>
>>> from email.header import decode_header
>>> decode_header('=?iso-8859-1?q?p=F6stal?=')
[(b'p\xf6stal', 'iso-8859-1')]
email.header.make_header(decoded_seq, maxlinelen=None, header_name=None, continuation_ws=' ')?

基于 decode_header() 所返回的數(shù)據(jù)對(duì)序列創(chuàng)建一個(gè) Header 實(shí)例。

decode_header() 接受一個(gè)標(biāo)頭值字符串并返回格式為 (decoded_string, charset) 的數(shù)據(jù)對(duì)序列,其中 charset 是字符集名稱。

這個(gè)函數(shù)接受這樣的數(shù)據(jù)對(duì)序列并返回一個(gè) Header 實(shí)例。 可選的 maxlinelen, header_namecontinuation_wsHeader 構(gòu)造器中的含義相同。