email.header
: 國際化標頭¶
原始碼: Lib/email/header.py
此模組是舊式 (Compat32
) 電子郵件 API 的一部分。在當前的 API 中,標頭的編碼和解碼由 EmailMessage
類的類字典 API 透明地處理。除了在舊式程式碼中使用外,該模組對於需要完全控制編碼標頭時所用字元集的應用程式也很有用。
本節的其餘文字是該模組的原始文件。
RFC 2822 是描述電子郵件格式的基礎標準。它源於較早的 RFC 822 標準,該標準在大多數電子郵件僅由 ASCII 字元組成的時代得到廣泛使用。RFC 2822 是一個假定電子郵件只包含 7-bit ASCII 字元的規範。
當然,隨著電子郵件在全球範圍內的部署,它已經變得國際化,現在可以在電子郵件中使用特定語言的字元集。基礎標準仍然要求電子郵件僅使用 7-bit ASCII 字元進行傳輸,因此已經編寫了大量的 RFC 來描述如何將包含非 ASCII 字元的電子郵件編碼為符合 RFC 2822 的格式。這些 RFC 包括 RFC 2045、RFC 2046、RFC 2047 和 RFC 2231。email
包在其 email.header
和 email.charset
模組中支援這些標準。
如果希望在電子郵件標頭中包含非 ASCII 字元,例如在 Subject 或 To 欄位中,則應使用 Header
類,並將 Message
物件中的欄位賦值為 Header
的例項,而不是為標頭值使用字串。從 email.header
模組中匯入 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 字元的。我們透過建立一個 Header
例項,並傳入位元組串所編碼的字元集來實現這一點。當隨後的 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')¶
建立一個符合 MIME 標準的標頭,可以包含不同字元集的字串。
可選引數 s 是初始標頭值。如果為
None
(預設值),則不設定初始標頭值。之後可以使用append()
方法呼叫來追加內容到標頭中。s 可以是bytes
或str
的例項,但其語義請參見append()
的文件。可選引數 charset 有兩個作用:它與
append()
方法的 charset 引數具有相同的含義。它還為所有後續省略 charset 引數的append()
呼叫設定預設字元集。如果在建構函式中未提供 charset(預設情況),則us-ascii
字元集將同時用作 s 的初始字元集和後續append()
呼叫的預設字元集。最大行長度可以透過 maxlinelen 顯式指定。為了將第一行拆分得更短(以考慮未包含在 s 中的欄位標頭,例如 Subject),請在 header_name 中傳入欄位的名稱。預設的 maxlinelen 是 78,而 header_name 的預設值是
None
,表示在處理長、分行的標頭的第一行時不考慮它。可選的 continuation_ws 必須是符合 RFC 2822 的摺疊空白,通常是空格或硬製表符。此字元將被新增到續行的開頭。continuation_ws 預設為單個空格字元。
可選的 errors 引數會直接傳遞給
append()
方法。- append(s, charset=None, errors='strict')¶
將字串 s 附加到 MIME 標頭。
可選的 charset 如果給出,應該是一個
Charset
例項(參見email.charset
)或字元集的名稱,它將被轉換為一個Charset
例項。值為None
(預設值)意味著使用建構函式中給定的 charset。s 可以是
bytes
或str
的例項。如果它是bytes
的例項,那麼 charset 是該位元組串的編碼,如果字串無法用該字元集解碼,則會引發UnicodeError
。如果 s 是
str
的例項,那麼 charset 是一個提示,指定字串中字元的字元集。在任何一種情況下,當使用 RFC 2047 規則生成符合 RFC 2822 標準的標頭時,字串將使用字元集的輸出編解碼器進行編碼。如果字串無法使用輸出編解碼器進行編碼,則會引發 UnicodeError。
如果 s 是一個位元組字串,可選的 errors 會作為 errors 引數傳遞給 decode 呼叫。
- encode(splitchars=';, \t', maxlinelen=None, linesep='\n')¶
將訊息標頭編碼為符合 RFC 的格式,可能會對長行進行換行,並將非 ASCII 部分封裝在 base64 或 quoted-printable 編碼中。
可選的 splitchars 是一個字串,包含在正常標頭換行期間拆分演算法應給予額外權重的字元。這非常粗略地支援 RFC 2822 的“更高級別語法中斷”:在拆分行時,以 splitchar 結尾的拆分點更受青睞,字元的偏好順序按其在字串中出現的順序排列。字串中可以包含空格和製表符,以指示當其他拆分字元未出現在被拆分的行中時,是否應優先選擇其中一個作為拆分點。Splitchars 不影響 RFC 2047 編碼的行。
如果給定 maxlinelen,它將覆蓋例項的最大行長度值。
linesep 指定用於分隔摺疊標頭行的字元。它預設為對 Python 應用程式程式碼最有用的值 (
\n
),但可以指定\r\n
以生成具有符合 RFC 的行分隔符的標頭。在 3.2 版本發生變更: 添加了 linesep 引數。
Header
類還提供了許多方法來支援標準運算子和內建函式。
email.header
模組還提供了以下便捷函式。
- email.header.decode_header(header)¶
解碼訊息標頭值,而不轉換字元集。標頭值在 header 中。
由於歷史原因,此函式可能返回以下任一內容:
一個包含標頭每個已解碼部分的元組列表
(decoded_bytes, charset)
,其中 decoded_bytes 始終是bytes
的例項,而 charset 是包含指定字元集名稱的小寫字串。
對於標頭的未編碼部分,為
None
。
一個長度為 1 的列表,包含一個元組
(string, None)
,其中 string 始終是str
的例項。
當發生某些解碼錯誤時(例如 base64 解碼異常),可能會引發
email.errors.HeaderParseError
。以下是示例:
>>> from email.header import decode_header >>> decode_header('=?iso-8859-1?q?p=F6stal?=') [(b'p\xf6stal', 'iso-8859-1')] >>> decode_header('unencoded_string') [('unencoded_string', None)] >>> decode_header('bar =?utf-8?B?ZsOzbw==?=') [(b'bar ', None), (b'f\xc3\xb3o', 'utf-8')]
備註
此函式僅為向後相容而存在。對於新程式碼,我們建議使用
email.headerregistry.HeaderRegistry
。
- email.header.make_header(decoded_seq, maxlinelen=None, header_name=None, continuation_ws=' ')¶
從
decode_header()
返回的元組序列建立一個Header
例項。decode_header()
接受一個標頭值字串,並返回一個格式為(decoded_string, charset)
的元組序列,其中 charset 是字元集的名稱。此函式接受這樣一個元組序列,並返回一個
Header
例項。可選的 maxlinelen、header_name 和 continuation_ws 與Header
建構函式中的相同。備註
此函式僅為向後相容而存在,不建議在新程式碼中使用。