email.header: 國際化標頭?
源代碼: Lib/email/header.py
此模塊是舊式 (Compat32) email API 的一部分。 在當前的 API 中標頭的編碼和解碼是由 EmailMessage 類的字典型 API 來透明地處理的。 除了在舊有代碼中使用,此模塊在需要完全控制當編碼標頭時所使用的字符集時也很有用處。
本段落中的剩余文本是該模塊的原始文檔。
RFC 2822 是描述電子郵件消息格式的基礎標準。 它派生自更早的 RFC 822 標準,該標準在大多數電子郵件僅由 ASCII 字符組成時已被廣泛使用。 RFC 2822 所描述的規范假定電子郵件都只包含 7 位 ASCII 字符。
當然,隨著電子郵件在全球部署,它已經變得國際化了,例如電子郵件消息中現在可以使用特定語言的專屬字符集。 這個基礎標準仍然要求電子郵件消息只使用 7 位 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 可以顯式指定最大行長度。 要將第一行拆分為更短的值 (以適應未被包括在to account for the field header which isn't included in s 中的字段標頭,例如 Subject),則將字段名稱作為 header_name 傳入。 maxlinelen 默認值為 76,而 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。
可選的 errors 會在 s 為字節串時被作為 errors 參數傳遞給 decode 調用。
-
encode(splitchars=';, \t', maxlinelen=None, linesep='\n')? 將消息標頭編碼為符合 RFC 的格式,可能會對過長的行采取折行并將非 ASCII 部分以 base64 或 quoted-printable 編碼格式進行封裝。
可選的 splitchars 是一個字符串,其中包含應在正常的標頭折行處理期間由拆分算法賦予額外權重的字符。 這是對于 RFC 2822 中 '更高層級語法拆分' 的很粗略的支持:在拆分期間會首選在 splitchar 之前的拆分點,字符的優先級是基于它們在字符串中的出現順序。 字符串中可包含空格和制表符以指明當其他拆分字符未在被拆分行中出現時是否要將某個字符作為優先于另一個字符的首選拆分點。 拆分字符不會影響以 RFC 2047 編碼的行。
如果給出 maxlinelen,它將覆蓋實例的最大行長度值。
linesep 指定用來分隔已折疊標頭行的字符。 它默認為 Python 應用程序代碼中最常用的值 (
\n),但也可以指定為\r\n以便產生帶有符合 RFC 的行分隔符的標頭。在 3.2 版更改: 增加了 linesep 參數。
Header類還提供了一些方法以支持標準運算符和內置函數。-
email.header 模塊還提供了下列便捷函數。
-
email.header.decode_header(header)? 在不轉換字符集的情況下對消息標頭值進行解碼。 header 為標頭值。
這個函數返回一個
(decoded_string, charset)對的列表,其中包含標頭的每個已解碼部分。 對于標頭的未編碼部分 charset 為None,在其他情況下則為一個包含已編碼字符串中所指定字符集名稱的小寫字符串。以下是為示例代碼:
>>> 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實例。 可選的 maxlinelen, header_name 和 continuation_ws 與Header構造器中的含義相同。
