email.policy
: Policy 物件¶
3.3 版本新增。
原始碼: Lib/email/policy.py
email
包的主要重點是處理各種電子郵件和 MIME RFC 中描述的電子郵件訊息。然而,電子郵件訊息的一般格式(一個由名稱後跟冒號,後跟值的頭部欄位組成,整個塊後跟一個空行和一個任意的“主體”),是一種在電子郵件領域之外也很有用的格式。其中一些用法相當符合主要的電子郵件 RFC,有些則不然。即使在使用電子郵件時,有時也需要打破對 RFC 的嚴格遵守,例如生成與不遵循標準或以違反標準的方式實現您想要使用的擴充套件的電子郵件伺服器互操作的電子郵件。
Policy 物件為 email 包提供了處理所有這些不同用例的靈活性。
Policy
物件封裝了一組屬性和方法,這些屬性和方法控制 email 包在使用期間的各種元件的行為。Policy
例項可以傳遞給 email 包中的各種類和方法,以更改預設行為。下面描述了可設定的值及其預設值。
email 包中的所有類都使用預設的 policy。 對於所有 parser
類和相關的便捷函式,以及 Message
類,這是 Compat32
policy,透過其對應的預定義例項 compat32
。此 policy 提供與 Python 3.3 之前的 email 包版本的完全向後相容性(在某些情況下,包括 bug 相容性)。
對於 EmailMessage
,*policy* 關鍵字的此預設值為 EmailPolicy
policy,透過其預定義例項 default
。
當建立 Message
或 EmailMessage
物件時,它會獲取 policy。 如果訊息是由 parser
建立的,則傳遞給解析器的 policy 將是其建立的訊息所使用的 policy。 如果訊息是由程式建立的,則可以在建立時指定 policy。 當將訊息傳遞給 generator
時,生成器預設使用訊息中的 policy,但您也可以將特定的 policy 傳遞給生成器,這將覆蓋儲存在訊息物件上的 policy。
對於 email.parser
類和解析器便捷函式,*policy* 關鍵字的預設值將在未來版本的 Python 中更改。 因此,在呼叫 parser
模組中描述的任何類和函式時,您應該始終明確指定您想要使用的 policy。
本文件的第一部分介紹了 Policy
的特性,它是一個 抽象基類,定義了所有 policy 物件通用的特性,包括 compat32
。這包括由 email 包在內部呼叫的某些鉤子方法,自定義 policy 可以覆蓋這些方法以獲得不同的行為。第二部分描述了具體類 EmailPolicy
和 Compat32
,它們分別實現提供標準行為和向後相容行為和特性的鉤子。
Policy
例項是不可變的,但可以克隆,接受與類建構函式相同的關鍵字引數,並返回一個新的 Policy
例項,該例項是原始例項的副本,但指定了已更改的屬性值。
例如,以下程式碼可用於從磁碟上的檔案中讀取電子郵件訊息,並將其傳遞給 Unix 系統上的系統 sendmail
程式
>>> from email import message_from_binary_file
>>> from email.generator import BytesGenerator
>>> from email import policy
>>> from subprocess import Popen, PIPE
>>> with open('mymsg.txt', 'rb') as f:
... msg = message_from_binary_file(f, policy=policy.default)
...
>>> p = Popen(['sendmail', msg['To'].addresses[0]], stdin=PIPE)
>>> g = BytesGenerator(p.stdin, policy=msg.policy.clone(linesep='\r\n'))
>>> g.flatten(msg)
>>> p.stdin.close()
>>> rc = p.wait()
在這裡,我們告訴 BytesGenerator
在建立要輸入到 sendmail
的 stdin
的二進位制字串時使用符合 RFC 的行分隔符字元,其中預設 policy 將使用 \n
行分隔符。
某些 email 包方法接受 *policy* 關鍵字引數,允許為該方法覆蓋 policy。 例如,以下程式碼使用上一個示例中 *msg* 物件的 as_bytes()
方法,並使用其執行平臺的本機行分隔符將訊息寫入檔案
>>> import os
>>> with open('converted.txt', 'wb') as f:
... f.write(msg.as_bytes(policy=msg.policy.clone(linesep=os.linesep)))
17
也可以使用加法運算子組合 Policy 物件,生成一個 policy 物件,其設定是求和物件的非預設值的組合
>>> compat_SMTP = policy.compat32.clone(linesep='\r\n')
>>> compat_strict = policy.compat32.clone(raise_on_defect=True)
>>> compat_strict_SMTP = compat_SMTP + compat_strict
此操作不可交換;也就是說,物件的新增順序很重要。為了說明
>>> policy100 = policy.compat32.clone(max_line_length=100)
>>> policy80 = policy.compat32.clone(max_line_length=80)
>>> apolicy = policy100 + policy80
>>> apolicy.max_line_length
80
>>> apolicy = policy80 + policy100
>>> apolicy.max_line_length
100
- class email.policy.Policy(**kw)¶
這是所有 policy 類的 抽象基類。它為幾個瑣碎的方法提供預設實現,以及不可變屬性、
clone()
方法和建構函式語義的實現。可以將各種關鍵字引數傳遞給 policy 類的建構函式。可以指定的引數是此類上的任何非方法屬性,以及具體類上的任何其他非方法屬性。建構函式中指定的值將覆蓋相應屬性的預設值。
此類定義了以下屬性,因此可以將以下值傳遞給任何 policy 類的建構函式
- linesep¶
用於終止序列化輸出中行的字串。預設值為
\n
,因為這是 Python 使用的內部行尾規範,儘管 RFC 需要\r\n
。
- cte_type¶
控制可能使用或必須使用的內容傳輸編碼型別。可能的值為
7bit
所有資料必須是“7 位乾淨”(僅限 ASCII)。這意味著在必要時,資料將使用 quoted-printable 或 base64 編碼進行編碼。
8bit
資料不限於 7 位乾淨。標頭中的資料仍然必須是僅限 ASCII 的,因此會被編碼(請參閱下面的
fold_binary()
和utf8
,瞭解例外情況),但主體部分可以使用8bit
CTE。cte_type
值為8bit
僅適用於BytesGenerator
,而不適用於Generator
,因為字串不能包含二進位制資料。如果Generator
在指定cte_type=8bit
的策略下執行,它將表現得好像cte_type
為7bit
。
- raise_on_defect¶
如果為
True
,則遇到的任何缺陷都將作為錯誤引發。如果為False
(預設值),缺陷將傳遞給register_defect()
方法。
- mangle_from_¶
如果為
True
,則主體中以 “From “ 開頭的行將透過在其前面放置一個>
來轉義。當訊息由生成器序列化時,將使用此引數。預設值:False
。在 3.5 版本中新增。
- verify_generated_headers¶
如果為
True
(預設值),生成器將引發HeaderWriteError
,而不是寫入不正確摺疊或分隔的標頭,以致它將被解析為多個標頭或與相鄰資料連線。此類標頭可以透過自定義標頭類或email
模組中的錯誤生成。由於它是一個安全功能,即使在
Compat32
策略中,此值也預設為True
。對於向後相容但存在不安全行為的情況,必須顯式將其設定為False
。在 3.13 版本中新增。
以下
Policy
方法旨在由使用 email 庫的程式碼呼叫,以建立具有自定義設定的策略例項其餘的
Policy
方法由 email 包程式碼呼叫,不打算由使用 email 包的應用程式呼叫。自定義策略必須實現所有這些方法。- handle_defect(obj, defect)¶
處理在 obj 上找到的 defect。當 email 包呼叫此方法時,defect 將始終是
Defect
的子類。預設實現檢查
raise_on_defect
標誌。如果為True
,則將 defect 作為異常引發。如果為False
(預設值),則將 obj 和 defect 傳遞給register_defect()
。
- register_defect(obj, defect)¶
在 obj 上註冊一個 defect。在 email 包中,defect 將始終是
Defect
的子類。預設實現呼叫 obj 的
defects
屬性的append
方法。當 email 包呼叫handle_defect
時,obj 通常會有一個具有append
方法的defects
屬性。與 email 包一起使用的自定義物件型別(例如,自定義Message
物件)也應提供這樣的屬性,否則解析訊息中的缺陷將引發意外錯誤。
- header_max_count(name)¶
返回名為 name 的標頭允許的最大數量。
當將標頭新增到
EmailMessage
或Message
物件時呼叫。如果返回的值不是0
或None
,並且已經存在多個名為 name 的標頭大於或等於返回的值,則會引發ValueError
。由於
Message.__setitem__
的預設行為是將值附加到標頭列表,因此很容易在不知不覺中建立重複的標頭。此方法允許對某些標頭進行限制,以限制可以透過程式設計方式新增到Message
的該標頭的例項數量。(解析器不會觀察此限制,它會忠實地生成訊息中存在的儘可能多的標頭。)預設實現為所有標頭名稱返回
None
。
- header_source_parse(sourcelines)¶
email 包使用一個字串列表呼叫此方法,每個字串都以在要解析的源中找到的行分隔符字元結尾。第一行包括欄位標頭名稱和分隔符。源中的所有空格都會被保留。該方法應返回要儲存在
Message
中以表示已解析標頭的(name, value)
元組。如果實現希望保留與現有 email 包策略的相容性,則 name 應該是保留大小寫的名稱(直到 ‘
:
’ 分隔符的所有字元),而 value 應該是不折疊的值(刪除了所有行分隔符字元,但保留了空格),並刪除了前導空格。sourcelines 可能包含 surrogateescaped 二進位制資料。
沒有預設實現
- header_store_parse(name, value)¶
當應用程式在以程式設計方式修改
Message
(而不是由解析器建立的Message
)時,email 包使用應用程式提供的名稱和值呼叫此方法。該方法應返回要儲存在Message
中以表示標頭的(name, value)
元組。如果實現希望保留與現有 email 包策略的相容性,則 name 和 value 應該是字串或不更改傳入引數內容的字串子類。
沒有預設實現
- header_fetch_parse(name, value)¶
當應用程式請求該標頭時,email 包會使用當前儲存在
Message
中的name 和 value 呼叫此方法,並且該方法返回的任何內容都會作為檢索到的標頭值傳遞迴應用程式。請注意,Message
中可能儲存了多個具有相同名稱的標頭;該方法會傳遞特定標頭的名稱和值,該標頭註定要返回給應用程式。value 可能包含 surrogateescaped 二進位制資料。該方法返回的值中不應包含 surrogateescaped 二進位制資料。
沒有預設實現
- class email.policy.EmailPolicy(**kw)¶
這個具體的
Policy
提供了旨在完全符合當前電子郵件 RFC 的行為。這些包括(但不限於)RFC 5322、RFC 2047 和當前的 MIME RFC。此策略添加了新的標頭解析和摺疊演算法。標頭不再是簡單的字串,而是
str
子類,其屬性取決於欄位的型別。解析和摺疊演算法完全實現了 RFC 2047 和 RFC 5322。message_factory
屬性的預設值是EmailMessage
。除了上面列出的適用於所有策略的可設定屬性之外,此策略還添加了以下附加屬性
在 3.6 版本中新增: [1]
- utf8¶
如果為
False
,則遵循 RFC 5322,透過將非 ASCII 字元編碼為“編碼字”來支援它們。如果為True
,則遵循 RFC 6532,並對標頭使用utf-8
編碼。以這種方式格式化的訊息可能會傳遞給支援SMTPUTF8
擴充套件的 SMTP 伺服器 (RFC 6531)。
- refold_source¶
如果
Message
物件中標頭的值來自parser
(而不是由程式設定),則此屬性指示在將訊息轉換回序列化形式時,生成器是否應重新摺疊該值。可能的值為none
所有源值都使用原始摺疊
long
任何行長度超過
max_line_length
的源值將被重新摺疊all
所有值都將被重新摺疊。
預設值為
long
。
- header_factory¶
一個可呼叫物件,它接受兩個引數,
name
和value
,其中name
是標頭欄位名稱,value
是未摺疊的標頭欄位值,並返回表示該標頭的字串子類。提供了一個預設的header_factory
(請參閱headerregistry
),該工廠支援對各種地址和日期 RFC 5322 標頭欄位型別以及主要的 MIME 標頭欄位型別進行自定義解析。將來將新增對其他自定義解析的支援。
- content_manager¶
一個物件,至少具有兩個方法:get_content 和 set_content。當呼叫
get_content()
或set_content()
方法時,EmailMessage
物件會呼叫此物件的相應方法,並將其作為第一個引數傳遞給訊息物件,並將傳遞給它的任何引數或關鍵字作為附加引數。預設情況下,content_manager
設定為raw_data_manager
。在 3.4 版本中新增。
該類提供了
Policy
的抽象方法的以下具體實現- header_source_parse(sourcelines)¶
名稱被解析為直到“
:
”的所有內容,並按原樣返回。該值透過剝離第一行的開頭空格、將所有後續行連線在一起並剝離任何尾隨回車符或換行符來確定。
- header_store_parse(name, value)¶
名稱保持不變地返回。如果輸入值具有
name
屬性並且它與 name (忽略大小寫)匹配,則該值保持不變地返回。否則,會將 name 和 value 傳遞給header_factory
,並將生成的標頭物件作為值返回。在這種情況下,如果輸入值包含 CR 或 LF 字元,則會引發ValueError
。
- header_fetch_parse(name, value)¶
如果值具有
name
屬性,則將其原樣返回。否則,將刪除任何 CR 或 LF 字元的 _name_ 和 _value_ 傳遞給header_factory
,並返回生成的標頭物件。任何被代理轉義的位元組都會轉換為 Unicode 的未知字元字形。
- fold(name, value)¶
標頭摺疊由
refold_source
策略設定控制。如果值不具有name
屬性,則認為它是“源值”(具有name
屬性意味著它某種形式的標頭物件)。如果根據策略需要重新摺疊源值,則透過將刪除任何 CR 和 LF 字元的 _name_ 和 _value_ 傳遞給header_factory
將其轉換為標頭物件。標頭物件的摺疊是透過使用當前策略呼叫其fold
方法來完成的。使用
splitlines()
將源值拆分為多行。如果該值不重新摺疊,則使用策略中的linesep
重新連線這些行並返回。例外情況是包含非 ASCII 二進位制資料的行。在這種情況下,無論refold_source
設定如何,該值都會被重新摺疊,這會導致使用unknown-8bit
字元集對二進位制資料進行 CTE 編碼。
以下 EmailPolicy
例項提供了適用於特定應用領域的預設值。請注意,在將來,這些例項(特別是 HTTP
例項)的行為可能會被調整,以更加符合與其領域相關的 RFC。
- email.policy.default¶
所有預設值均未更改的
EmailPolicy
例項。此策略使用標準的 Python\n
行尾符,而不是 RFC 正確的\r\n
。
- email.policy.SMTP¶
適用於根據電子郵件 RFC 序列化訊息。與
default
類似,但linesep
設定為符合 RFC 的\r\n
。
- email.policy.SMTPUTF8¶
與
SMTP
相同,只是utf8
為True
。在不使用標頭中的編碼詞的情況下序列化訊息到訊息儲存很有用。僅當發件人或收件人地址包含非 ASCII 字元時,才應將其用於 SMTP 傳輸(smtplib.SMTP.send_message()
方法會自動處理此問題)。
- email.policy.HTTP¶
適用於序列化標頭以在 HTTP 流量中使用。與
SMTP
類似,只是max_line_length
設定為None
(無限制)。
- email.policy.strict¶
便利例項。與
default
相同,只是raise_on_defect
設定為True
。這允許透過編寫以下內容使任何策略變得嚴格somepolicy + policy.strict
對於所有這些 EmailPolicies
,電子郵件包的有效 API 從 Python 3.2 API 更改為以下方式
在
Message
上設定標頭會導致解析該標頭並建立標頭物件。從
Message
獲取標頭值會導致解析該標頭並建立並返回標頭物件。任何標頭物件或由於策略設定而重新摺疊的任何標頭都使用完全實現 RFC 摺疊演算法的演算法進行摺疊,包括知道在何處需要和允許編碼詞。
從應用程式檢視來看,這意味著透過 EmailMessage
獲得的任何標頭都是具有額外屬性的標頭物件,其字串值是標頭的完全解碼的 Unicode 值。同樣,可以使用 Unicode 字串為標頭分配新值或建立新標頭,並且策略將負責將 Unicode 字串轉換為正確的 RFC 編碼形式。
標頭物件及其屬性在 headerregistry
中進行了描述。
- class email.policy.Compat32(**kw)¶
此具體
Policy
是向後相容性策略。它複製了 Python 3.2 中電子郵件包的行為。policy
模組還定義了此類的例項compat32
,該例項用作預設策略。因此,電子郵件包的預設行為是保持與 Python 3.2 的相容性。以下屬性的值與
Policy
預設值不同- mangle_from_¶
預設值為
True
。
該類提供了
Policy
的抽象方法的以下具體實現- header_source_parse(sourcelines)¶
名稱被解析為直到“
:
”的所有內容,並按原樣返回。該值透過剝離第一行的開頭空格、將所有後續行連線在一起並剝離任何尾隨回車符或換行符來確定。
- header_store_parse(name, value)¶
名稱和值原樣返回。
腳註