email.header:國際化標頭

原始碼: Lib/email/header.py


此模組是舊版 (Compat32) 電子郵件 API 的一部分。在當前的 API 中,標頭的編碼和解碼由 EmailMessage 類的類似字典的 API 透明地處理。除了在舊程式碼中使用之外,此模組在需要完全控制編碼標頭時使用的字元集的應用程式中也很有用。

本節的其餘文字是該模組的原始文件。

RFC 2822 是描述電子郵件訊息格式的基本標準。它源自較舊的 RFC 822 標準,該標準在大多數電子郵件僅由 ASCII 字元組成時得到廣泛使用。RFC 2822 是一項規範,編寫時假設電子郵件僅包含 7 位 ASCII 字元。

當然,隨著電子郵件在全球範圍內的部署,它已經國際化,現在可以在電子郵件訊息中使用特定於語言的字元集。基本標準仍然要求僅使用 7 位 ASCII 字元傳輸電子郵件訊息,因此編寫了一系列 RFC 來描述如何將包含非 ASCII 字元的電子郵件編碼為符合 RFC 2822 的格式。這些 RFC 包括 RFC 2045RFC 2046RFC 2047RFC 2231email 包在其 email.headeremail.charset 模組中支援這些標準。

如果要在電子郵件標頭中包含非 ASCII 字元,例如在 SubjectTo 欄位中,則應使用 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 可以是 bytesstr 的例項,但請參閱 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 可以是 bytesstr 的例項。如果它是 bytes 的例項,則 charset 是該位元組字串的編碼,如果無法使用該字元集解碼字串,則會引發 UnicodeError

如果 sstr 的例項,則 charset 是一個提示,指定字串中字元的字元集。

在任何一種情況下,當使用 RFC 2822 規則,生成符合 RFC 2047 規則的頭部時,該字串將使用字元集的輸出編解碼器進行編碼。 如果字串無法使用輸出編解碼器進行編碼,則會引發 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 類還提供了許多方法來支援標準運算子和內建函式。

__str__()

返回 Header 的近似字串表示,使用無限的行長度。所有片段都使用指定的編碼轉換為 unicode 並適當地連線在一起。任何字元集為 'unknown-8bit' 的片段都將使用 'replace' 錯誤處理程式解碼為 ASCII。

在 3.2 版本中更改: 添加了對 'unknown-8bit' 字元集的處理。

__eq__(other)

此方法允許您比較兩個 Header 例項是否相等。

__ne__(other)

此方法允許您比較兩個 Header 例項是否不相等。

email.header 模組還提供了以下方便的函式。

email.header.decode_header(header)

解碼訊息頭的值,而不轉換字元集。頭部值位於 header 中。

此函式返回一個 (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() 返回的成對序列建立 Header 例項。

decode_header() 接受頭部值字串並返回格式為 (decoded_string, charset) 的對序列,其中 charset 是字元集的名稱。

此函式接受其中一個成對序列,並返回一個 Header 例項。可選的 maxlinelenheader_namecontinuation_wsHeader 建構函式中的相同。