email.header: 國際化標頭?

源代碼: Lib/email/header.py


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

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

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

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

如果你想在你的電子郵件標頭中包括非 ASCII 字符,比如說是在 SubjectTo 字段中,你應(yīng)當使用 Header 類并將 Message 對象中的字段賦值為 Header 的實例而不是使用字符串作為字段值。 請從 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)建一個 Header 實例并傳入字節(jié)串編碼所用的字符集來做到這一點。 當后續(xù)的 Message 實例被展平時,Subject 字段會正確地按 RFC 2047 來編碼。 可感知 MIME 的電子郵件閱讀器將會使用嵌入的 ISO-8859-1 字符來顯示此標頭。

以下是 Header 類描述:

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

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

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

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

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

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

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

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

將字符串 s 添加到 MIME 標頭。

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

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

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

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

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

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

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

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

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

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

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

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

__str__()?

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

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

__eq__(other)?

這個方法允許你對兩個 Header 實例進行相等比較。

__ne__(other)?

這個方法允許你對兩個 Header 實例進行不等比較。

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

email.header.decode_header(header)?

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

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

以下是為示例代碼:

>>>
>>> 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ù)對序列創(chuàng)建一個 Header 實例。

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

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