email.headerregistry
: 自定義標頭物件¶
原始碼: Lib/email/headerregistry.py
3.6 版本新增: [1]
標頭由 str
的自定義子類表示。用於表示給定標頭的特定類由建立標頭時生效的 header_factory
的 policy
確定。本節記錄了 email 包為處理符合 RFC 5322 的電子郵件訊息而實現的特定 header_factory
,它不僅為各種標頭型別提供了自定義標頭物件,還為應用程式提供了擴充套件機制來新增其自己的自定義標頭型別。
當使用任何從 EmailPolicy
派生的 policy 物件時,所有標頭都由 HeaderRegistry
生成,並且以 BaseHeader
作為它們的最後一個基類。每個標頭類都有一個附加的基類,該基類由標頭的型別確定。例如,許多標頭都有 UnstructuredHeader
類作為它們的另一個基類。標頭的專門化第二個類由標頭的名稱確定,使用儲存在 HeaderRegistry
中的查詢表。所有這些都為典型的應用程式程式透明地管理,但提供了介面來修改預設行為,供更復雜的應用程式使用。
以下各節首先記錄標頭基類及其屬性,然後是修改 HeaderRegistry
行為的 API,最後是用於表示從結構化標頭解析的資料的支援類。
- class email.headerregistry.BaseHeader(name, value)¶
name 和 value 從
header_factory
呼叫傳遞給BaseHeader
。任何標頭物件的字串值都是完全解碼為 unicode 的 value。此基類定義以下只讀屬性
- name¶
標頭的名稱(欄位中 ‘:’ 之前的部分)。這正是為 name 在
header_factory
呼叫中傳遞的值;也就是說,保留了大小寫。
- defects¶
HeaderDefect
例項的元組,報告在解析期間發現的任何 RFC 合規性問題。email 包嘗試完全檢測合規性問題。有關可能報告的缺陷型別,請參閱errors
模組。
- max_count¶
此型別標頭可以具有相同
name
的最大數量。None
值表示無限制。此屬性的BaseHeader
值為None
;預期專門化的標頭類將根據需要覆蓋此值。
BaseHeader
還提供了以下方法,該方法由 email 庫程式碼呼叫,通常不應由應用程式程式呼叫- fold(*, policy)¶
返回一個字串,其中包含
linesep
字元,以便根據 policy 正確摺疊標頭。cte_type
為8bit
將被視為7bit
,因為標頭可能不包含任意二進位制資料。如果utf8
為False
,則非 ASCII 資料將進行 RFC 2047 編碼。
BaseHeader
本身不能用於建立標頭物件。它定義了每個專門的標頭為生成標頭物件而與之協作的協議。具體來說,BaseHeader
要求專門化的類提供一個名為parse
的classmethod()
。此方法按如下方式呼叫parse(string, kwds)
kwds
是一個字典,其中包含一個預初始化的鍵defects
。defects
是一個空列表。parse 方法應將檢測到的任何缺陷附加到此列表。返回時,kwds
字典必須包含至少鍵decoded
和defects
的值。decoded
應為標頭的字串值(即,完全解碼為 unicode 的標頭值)。parse 方法應假定 string 可能包含內容傳輸編碼的部分,但應正確處理所有有效的 unicode 字元,以便它可以解析未編碼的標頭值。BaseHeader
的__new__
然後建立標頭例項,並呼叫其init
方法。如果專門的類希望設定BaseHeader
本身提供的屬性之外的其他屬性,則只需提供init
方法。這樣的init
方法應如下所示def init(self, /, *args, **kw): self._myattr = kw.pop('myattr') super().init(*args, **kw)
也就是說,專門的類放入
kwds
字典中的任何額外內容都應刪除並處理,並且將kw
(和args
)的剩餘內容傳遞給BaseHeader
init
方法。
- class email.headerregistry.UnstructuredHeader¶
“非結構化”標頭是 RFC 5322 中的預設標頭型別。任何沒有指定語法的標頭都視為非結構化標頭。非結構化標頭的經典示例是 Subject 標頭。
在 RFC 5322 中,非結構化頭部是在 ASCII 字元集中執行的任意文字。RFC 2047 提供了一種 RFC 5322 相容的機制,用於在頭部值中將非 ASCII 文字編碼為 ASCII 字元。當包含編碼詞的值傳遞給建構函式時,
UnstructuredHeader
解析器會根據 RFC 2047 中非結構化文字的規則,將這些編碼詞轉換為 Unicode。解析器使用啟發式方法嘗試解碼某些不符合規範的編碼詞。在這種情況下會註冊缺陷,以及在編碼詞或非編碼文字中存在無效字元等問題的缺陷。此頭部型別不提供其他屬性。
- class email.headerregistry.DateHeader¶
RFC 5322 為電子郵件頭部中的日期指定了非常具體的格式。
DateHeader
解析器可以識別該日期格式,並識別有時在“實際應用中”發現的許多變體形式。此頭部型別提供以下附加屬性
- datetime¶
如果頭部值可以被識別為某種形式的有效日期,則此屬性將包含一個
datetime
例項,表示該日期。如果輸入日期的時區指定為-0000
(表示它在 UTC 中,但不包含有關源時區的任何資訊),則datetime
將是一個樸素的datetime
。如果找到特定的時區偏移量(包括+0000
),則datetime
將包含一個感知時區的datetime
,它使用datetime.timezone
來記錄時區偏移量。
頭部的
decoded
值由根據 RFC 5322 規則格式化datetime
來確定;也就是說,它被設定為email.utils.format_datetime(self.datetime)
建立
DateHeader
時,value 可以是datetime
例項。這意味著,例如,以下程式碼是有效的並且可以按預期工作msg['Date'] = datetime(2011, 7, 15, 21)
因為這是一個樸素的
datetime
,它將被解釋為 UTC 時間戳,並且結果值將具有-0000
的時區。更有用的是使用來自utils
模組的localtime()
函式msg['Date'] = utils.localtime()
此示例使用當前時區偏移量將日期頭部設定為當前時間和日期。
- class email.headerregistry.AddressHeader¶
地址頭部是最複雜的結構化頭部型別之一。
AddressHeader
類為任何地址頭部提供通用介面。此頭部型別提供以下附加屬性
- groups¶
一個
Group
物件的元組,用於編碼頭部值中找到的地址和組。不屬於組的地址在此列表中表示為單地址Groups
,其display_name
為None
。
- addresses¶
一個
Address
物件的元組,用於編碼頭部值中的所有單獨地址。如果頭部值包含任何組,則組中的各個地址將包含在列表中,該列表位於該組在值中出現的位置(也就是說,地址列表被“扁平化”為一維列表)。
頭部的
decoded
值將所有編碼詞解碼為 Unicode。idna
編碼的域名也被解碼為 Unicode。decoded
值由 拼接groups
屬性的元素的str
值和', '
來設定。任何組合中的
Address
和Group
物件的列表可用於設定地址頭部的值。display_name
為None
的Group
物件將被解釋為單個地址,這允許透過使用從源頭部的groups
屬性獲取的列表來複制包含組的地址列表。
- class email.headerregistry.SingleAddressHeader¶
AddressHeader
的子類,它添加了一個附加屬性- address¶
由頭部值編碼的單個地址。如果頭部值實際上包含多個地址(這會違反預設
policy
下的 RFC),則訪問此屬性將導致ValueError
。
上述許多類也有一個 Unique
變體(例如,UniqueUnstructuredHeader
)。唯一的區別是,在 Unique
變體中,max_count
設定為 1。
- class email.headerregistry.MIMEVersionHeader¶
MIME-Version 頭部實際上只有一個有效值,即
1.0
。為了面向未來,此頭部類支援其他有效的版本號。如果版本號具有 RFC 2045 中定義的有效值,則頭部物件對於以下屬性將具有非None
值- version¶
版本號為字串,刪除了所有空格和/或註釋。
- major¶
主要版本號為整數
- minor¶
次要版本號為整數
- class email.headerregistry.ParameterizedMIMEHeader¶
MIME 標頭都以 ‘Content-’ 字首開頭。每個特定的標頭都有一個特定的值,該值在相應標頭的類下描述。有些標頭還可以接受一系列補充引數,這些引數具有通用格式。此類別作為所有接受引數的 MIME 標頭的基類。
- params¶
一個字典,將引數名稱對映到引數值。
- class email.headerregistry.ContentTypeHeader¶
一個
ParameterizedMIMEHeader
類,用於處理 Content-Type 標頭。- content_type¶
內容型別字串,格式為
maintype/subtype
。
- maintype¶
- subtype¶
- class email.headerregistry.ContentDispositionHeader¶
一個
ParameterizedMIMEHeader
類,用於處理 Content-Disposition 標頭。- content_disposition¶
inline
和attachment
是常用的唯二有效值。
- class email.headerregistry.ContentTransferEncoding¶
處理 Content-Transfer-Encoding 標頭。
- class email.headerregistry.HeaderRegistry(base_class=BaseHeader, default_class=UnstructuredHeader, use_default_map=True)¶
這是
EmailPolicy
預設使用的工廠。HeaderRegistry
使用 base_class 和從其儲存的登錄檔中檢索的專用類動態構建用於建立標頭例項的類。當給定的標頭名稱未出現在登錄檔中時,由 default_class 指定的類將用作專用類。當 use_default_map 為True
(預設值)時,標頭名稱到類的標準對映將在初始化期間複製到登錄檔中。 base_class 始終是生成的類的__bases__
列表中的最後一個類。預設對映為
- subject:
UniqueUnstructuredHeader
- date:
UniqueDateHeader
- resent-date:
DateHeader
- orig-date:
UniqueDateHeader
- sender:
UniqueSingleAddressHeader
- resent-sender:
SingleAddressHeader
- to:
UniqueAddressHeader
- resent-to:
AddressHeader
- cc:
UniqueAddressHeader
- resent-cc:
AddressHeader
- bcc:
UniqueAddressHeader
- resent-bcc:
AddressHeader
- from:
UniqueAddressHeader
- resent-from:
AddressHeader
- reply-to:
UniqueAddressHeader
- mime-version:
MIMEVersionHeader
- content-type:
ContentTypeHeader
- content-disposition:
ContentDispositionHeader
- content-transfer-encoding:
ContentTransferEncodingHeader
- message-id:
MessageIDHeader
HeaderRegistry
具有以下方法- map_to_type(self, name, cls)¶
name 是要對映的標頭的名稱。它將在登錄檔中轉換為小寫。 cls 是要使用的專用類,與 base_class 一起使用,以建立用於例項化與 name 匹配的標頭的類。
- __getitem__(name)¶
構造並返回一個用於處理建立 name 標頭的類。
- __call__(name, value)¶
從登錄檔中檢索與 name 關聯的專用標頭(如果 name 未出現在登錄檔中,則使用 default_class),並將其與 base_class 組合以生成一個類,呼叫構造的類的建構函式,傳遞相同的引數列表,最後返回由此建立的類例項。
以下類是用於表示從結構化標頭解析的資料的類,並且通常可以由應用程式程式使用,以構造要分配給特定標頭的結構化值。
- class email.headerregistry.Address(display_name='', username='', domain='', addr_spec=None)¶
用於表示電子郵件地址的類。地址的一般形式為
[display_name] <username@domain>
或
username@domain
其中每個部分都必須符合 RFC 5322 中規定的特定語法規則。
為方便起見,可以指定 addr_spec 而不是 username 和 domain,在這種情況下,將從 addr_spec 解析 username 和 domain。 addr_spec 必須是正確 RFC 引用的字串;如果不是,
Address
將引發錯誤。允許使用 Unicode 字元,並且在序列化時將正確編碼。但是,根據 RFC,Unicode 不允許在地址的使用者名稱部分中使用。- display_name¶
地址的顯示名稱部分(如果有),刪除所有引號。如果地址沒有顯示名稱,則此屬性將為空字串。
- username¶
地址的
username
部分,刪除所有引號。
- domain¶
地址的
domain
部分。
- addr_spec¶
地址的
username@domain
部分,正確引用以用作裸地址(如上所示的第二種形式)。此屬性是不可變的。
為了支援 SMTP (RFC 5321),
Address
處理一種特殊情況:如果username
和domain
都是空字串(或None
),則Address
的字串值為<>
。
- class email.headerregistry.Group(display_name=None, addresses=None)¶
用於表示地址組的類。地址組的一般形式為
display_name: [address-list];
為了方便處理由組和單個地址混合組成的地址列表,
Group
也可以透過將 display_name 設定為None
並提供單個地址列表作為 addresses 來表示不屬於組的單個地址。- display_name¶
組的
display_name
。如果為None
且addresses
中恰好有一個Address
,則Group
表示不屬於組的單個地址。
腳註