email.header
: 國際化標頭?
源代碼: Lib/email/header.py
此模塊是舊式 (Compat32
) email API 的一部分。 在當前的 API 中標頭的編碼和解碼是由 EmailMessage
類(lèi)的字典型 API 來(lái)透明地處理的。 除了在舊有代碼中使用,此模塊在需要完全控制當編碼標頭時(shí)所使用的字符集時(shí)也很有用處。
本節中的其余文本是此模塊的原始文檔。
RFC 2822 是描述電子郵件消息格式的基礎標準。 它派生自更早的 RFC 822 標準,該標準在大多數電子郵件僅由 ASCII 字符組成時(shí)已被廣泛使用。 RFC 2822 所描述的規范假定電子郵件都只包含 7 位 ASCII 字符。
當然,隨著(zhù)電子郵件在全球部署,它已經(jīng)變得國際化了,例如電子郵件消息中現在可以使用特定語(yǔ)言的專(zhuān)屬字符集。 這個(gè)基礎標準仍然要求電子郵件消息只使用 7 位 ASCII 字符來(lái)進(jìn)行傳輸,為此編寫(xiě)了大量 RFC 來(lái)描述如何將包含非 ASCII 字符的電子郵件編碼為符合 RFC 2822 的格式。 這些 RFC 包括 RFC 2045, RFC 2046, RFC 2047 和 RFC 2231。 email
包在其 email.header
和 email.charset
模塊中支持了這些標準。
如果你想在你的電子郵件標頭中包括非 ASCII 字符,比如說(shuō)是在 Subject 或 To 字段中,你應當使用 Header
類(lèi)并將 Message
對象中的字段賦值為 Header
的實(shí)例而不是使用字符串作為字段值。 請從 email.header
模塊導入 Header
類(lèi)。 例如:
>>> 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 字符的? 我們通過(guò)創(chuàng )建一個(gè) Header
實(shí)例并傳入字節串編碼所用的字符集來(lái)做到這一點(diǎn)。 當后續的 Message
實(shí)例被展平時(shí),Subject 字段會(huì )正確地按 RFC 2047 來(lái)編碼。 可感知 MIME 的電子郵件閱讀器將會(huì )使用嵌入的 ISO-8859-1 字符來(lái)顯示此標頭。
以下是 Header
類(lèi)描述:
- class email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')?
創(chuàng )建符合 MIME 要求的標頭,其中可包含不同字符集的字符串。
可選的 s 是初始標頭值。 如果為
None
(默認值),則表示初始標頭值未設置。 你可以在稍后使用append()
方法調用向標頭添加新值。 s 可以是bytes
或str
的實(shí)例,注意參閱append()
文檔了解相關(guān)語(yǔ)義。可選的 charset 用于兩種目的:它的含義與
append()
方法的 charset 參數相同。 它還會(huì )為所有省略了 charset 參數的后續append()
調用設置默認字符集。 如果 charset 在構造器中未提供(默認設置),則會(huì )將us-ascii
字符集用作 s 的初始字符集以及后續append()
調用的默認字符集。通過(guò) maxlinelen 可以顯式指定最大行長(cháng)度。 要將第一行拆分為更短的值 (以適應未被包括在to account for the field header which isn't included in s 中的字段標頭,例如 Subject),則將字段名稱(chēng)作為 header_name 傳入。 maxlinelen 默認值為 76,而 header_name 默認值為
None
,表示不考慮拆分超長(cháng)標頭的第一行。可選的 continuation_ws 必須為符合 RFC 2822 的折疊用空白符,通常是空格符或硬制表符。 這個(gè)字符將被加綴至連續行的開(kāi)頭。 continuation_ws 默認為一個(gè)空格符。
可選的 errors 會(huì )被直接傳遞給
append()
方法。- append(s, charset=None, errors='strict')?
將字符串 s 添加到 MIME 標頭。
如果給出可選的 charset,它應當是一個(gè)
Charset
實(shí)例 (參見(jiàn)email.charset
) 或字符集名稱(chēng),該參數將被轉換為一個(gè)Charset
實(shí)例。 如果為None
(默認值) 則表示會(huì )使用構造器中給出的 charset。s 可以是
bytes
或str
的實(shí)例。 如果它是bytes
的實(shí)例,則 charset 為該字節串的編碼格式,如果字節串無(wú)法用該字符集來(lái)解碼則將引發(fā)UnicodeError
。如果 s 是
str
的實(shí)例,則 charset 是用來(lái)指定字符串中字符字符集的提示。在這兩種情況下,當使用 RFC 2047 規則產(chǎn)生符合 RFC 2822 的標頭時(shí),將使用指定字符集的輸出編解碼器來(lái)編碼字符串。 如果字符串無(wú)法使用該輸出編解碼器來(lái)編碼,則將引發(fā) UnicodeError。
可選的 errors 會(huì )在 s 為字節串時(shí)被作為 errors 參數傳遞給 decode 調用。
- encode(splitchars=';, \t', maxlinelen=None, linesep='\n')?
將消息標頭編碼為符合 RFC 的格式,可能會(huì )對過(guò)長(cháng)的行采取折行并將非 ASCII 部分以 base64 或 quoted-printable 編碼格式進(jìn)行封裝。
可選的 splitchars 是一個(gè)字符串,其中包含應在正常的標頭折行處理期間由拆分算法賦予額外權重的字符。 這是對于 RFC 2822 中 '更高層級語(yǔ)法拆分' 的很粗略的支持:在拆分期間會(huì )首選在 splitchar 之前的拆分點(diǎn),字符的優(yōu)先級是基于它們在字符串中的出現順序。 字符串中可包含空格和制表符以指明當其他拆分字符未在被拆分行中出現時(shí)是否要將某個(gè)字符作為優(yōu)先于另一個(gè)字符的首選拆分點(diǎn)。 拆分字符不會(huì )影響以 RFC 2047 編碼的行。
如果給出 maxlinelen,它將覆蓋實(shí)例的最大行長(cháng)度值。
linesep 指定用來(lái)分隔已折疊標頭行的字符。 它默認為 Python 應用程序代碼中最常用的值 (
\n
),但也可以指定為\r\n
以便產(chǎn)生帶有符合 RFC 的行分隔符的標頭。在 3.2 版更改: 增加了 linesep 參數。
Header
類(lèi)還提供了一些方法以支持標準運算符和內置函數。
email.header
模塊還提供了下列便捷函數。
- email.header.decode_header(header)?
在不轉換字符集的情況下對消息標頭值進(jìn)行解碼。 header 為標頭值。
這個(gè)函數返回一個(gè)
(decoded_string, charset)
對的列表,其中包含標頭的每個(gè)已解碼部分。 對于標頭的未編碼部分 charset 為None
,在其他情況下則為一個(gè)包含已編碼字符串中所指定字符集名稱(chēng)的小寫(xiě)字符串。以下是為示例代碼:
>>> 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()
所返回的數據對序列創(chuàng )建一個(gè)Header
實(shí)例。decode_header()
接受一個(gè)標頭值字符串并返回格式為(decoded_string, charset)
的數據對序列,其中 charset 是字符集名稱(chēng)。這個(gè)函數接受這樣的數據對序列并返回一個(gè)
Header
實(shí)例。 可選的 maxlinelen, header_name 和 continuation_ws 與Header
構造器中的含義相同。