email.headerregistry:自定义标题对象 — Python 文档

来自菜鸟教程
Python/docs/3.9/library/email.headerregistry
跳转至:导航、​搜索

email.headerregistry:自定义标题对象

源代码: :source:`Lib/email/headerregistry.py`



3.6 版新功能: 1


标头由 str 的自定义子类表示。 用于表示给定标头的特定类由创建标头时有效的 policyheader_factory 确定。 本节记录了由电子邮件包实现的特定 header_factory,用于处理 RFC 5322 兼容的电子邮件消息,它不仅为各种标题类型提供自定义标题对象,而且为应用程序提供了一种扩展机制来添加他们自己的自定义标头类型。

当使用派生自 EmailPolicy 的任何策略对象时,所有标头均由 HeaderRegistry 生成,并以 BaseHeader 作为其最后一个基类。 每个头类都有一个附加的基类,该基类由头的类型决定。 例如,许多标头将类 UnstructuredHeader 作为其其他基类。 标题的专用第二类由标题的名称确定,使用存储在 HeaderRegistry 中的查找表。 对于典型的应用程序,所有这些都是透明管理的,但是提供了用于修改默认行为以供更复杂的应用程序使用的接口。

下面的部分首先记录标头基类及其属性,然后是用于修改 HeaderRegistry 行为的 API,最后是用于表示从结构化标头解析的数据的支持类。

class email.headerregistry.BaseHeader(name, value)

namevalueheader_factory 调用传递给 BaseHeader。 任何标头对象的字符串值都是完全解码为 unicode 的

该基类定义了以下只读属性:

name

标题的名称(':' 之前的字段部分)。 这正是在 nameheader_factory 调用中传递的值; 也就是说,大小写被保留。

defects

HeaderDefect 实例的元组报告在解析过程中发现的任何 RFC 合规性问题。 电子邮件包试图完整地检测合规性问题。 有关可能报告的缺陷类型的讨论,请参阅 errors 模块。

max_count

可以具有相同 name 的此类标题的最大数量。 None 的值表示无限制。 该属性的BaseHeader值为None; 预计专用头类将根据需要覆盖此值。

BaseHeader还提供了如下方法,由邮件库代码调用,一般不应该被应用程序调用:

fold(*, policy)

根据 policy 正确折叠标头所需,返回包含 linesep 字符的字符串。 8bitcte_type 将被视为 7bit,因为标头可能不包含任意二进制数据。 如果 utf8False,非 ASCII 数据将被 RFC 2047 编码。

BaseHeader 本身不能用于创建头对象。 它定义了一个协议,每个专用标头与之合作以生成标头对象。 具体来说,BaseHeader 要求专门的类提供一个名为 parseclassmethod()。 该方法调用如下:

parse(string, kwds)

kwds 是一个包含一个预初始化键 defects 的字典。 defects 是一个空列表。 parse 方法应将任何检测到的缺陷附加到此列表中。 返回时,kwds 字典 必须 至少包含键 decodeddefects 的值。 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)的剩余内容传递给 [ X188X] init 方法。

class email.headerregistry.UnstructuredHeader

“非结构化”标头是 RFC 5322 中标头的默认类型。 任何没有指定语法的头都被视为非结构化的。 非结构化标头的经典示例是 Subject 标头。

RFC 5322 中,非结构化标题是 ASCII 字符集中的任意文本的运行。 然而,RFC 2047 具有 RFC 5322 兼容机制,用于将非 ASCII 文本编码为标头值中的 ASCII 字符。 当包含编码词的 value 传递给构造函数时,UnstructuredHeader 解析器将这些编码词转换为 unicode,遵循 RFC 2047 规则对于非结构化文本。 解析器使用试探法来尝试解码某些不合规的编码字。 在这种情况下会记录缺陷,以及编码字或非编码文本中的无效字符等问题的缺陷。

此标头类型不提供其他属性。

class email.headerregistry.DateHeader

RFC 5322 为电子邮件标题中的日期指定了一种非常具体的格式。 DateHeader 解析器识别该日期格式,以及识别有时“在野外”发现的许多变体形式。

此标头类型提供以下附加属性:

datetime

如果标题值可以被识别为一种或另一种形式的有效日期,则该属性将包含表示该日期的 datetime 实例。 如果输入日期的时区指定为 -0000(表明它是 UTC 但不包含有关源时区的信息),那么 datetime 将是一个朴素的 datetime ]。 如果找到特定的时区偏移量(包括 +0000),则 datetime 将包含使用 datetime.timezone 进行记录的感知 datetime时区偏移量。

头部的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_nameNone

addresses

Address 对象的元组,对标头值中的所有单个地址进行编码。 如果标头值包含任何组,则该组中的各个地址将包含在该值中出现该组的位置的列表中(即,地址列表被“扁平化”为一维列表)。

标头的 decoded 值将所有编码字解码为 unicode。 idna 编码的域名也被解码为 unicode。 decoded 值是通过 joingroups 属性的元素的 str 值与 ', ' 结合来设置的。

可以使用任意组合的 AddressGroup 对象的列表来设置地址头的值。 display_nameNoneGroup 对象将被解释为单个地址,这允许使用从 获取的列表完整地复制地址列表X189X] 源头的属性。

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

处理 Content-Type 标头的 ParameterizedMIMEHeader 类。

content_type

内容类型字符串,格式为 maintype/subtype

maintype
subtype
class email.headerregistry.ContentDispositionHeader
处理 Content-Disposition 标头的 ParameterizedMIMEHeader 类。
content_disposition
inlineattachment 是唯一常用的有效值。
class email.headerregistry.ContentTransferEncoding
处理 Content-Transfer-Encoding 标头。
cte
有效值为 7bit8bitbase64quoted-printable。 有关更多信息,请参阅 RFC 2045
class email.headerregistry.HeaderRegistry(base_class=BaseHeader, default_class=UnstructuredHeader, use_default_map=True)

这是 EmailPolicy 默认使用的工厂。 HeaderRegistry 使用 base_class 和从它持有的注册表中检索的专用类来构建用于动态创建头实例的类。 当给定的头名称没有出现在注册表中时,由 default_class 指定的类用作专用类。 当 use_default_mapTrue(默认值)时,标头名称到类的标准映射会在初始化期间复制到注册表中。 base_class 始终是生成的类的 __bases__ 列表中的最后一个类。

默认映射是:

主题

唯一非结构化头

日期

唯一日期头

重发日期

日期头

原始日期

唯一日期头

发件人

唯一的单一地址头

重发者

单地址头

唯一地址头

反感

地址头

抄送

唯一地址头

复抄抄送

地址头

密件抄送

唯一地址头

重新发送-密件抄送

地址头

唯一地址头

怨恨的

地址头

回复

唯一地址头

哑剧版

MIME 版本头

内容类型

内容类型标题

内容配置

内容处置头

内容传输编码

内容传输编码头

消息 ID

消息ID头


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 代替 usernamedomain,在这种情况下,usernamedomainaddr_spec 解析。 addr_spec 必须是正确的 RFC 引用字符串; 如果不是 Address 将引发错误。 Unicode 字符是允许的,并将在序列化时进行属性编码。 但是,根据 RFC,在地址的用户名部分中不允许使用 unicode not

display_name

地址的显示名称部分(如果有),并删除所有引用。 如果地址没有显示名称,则此属性将为空字符串。

username

地址的 username 部分,删除了所有引用。

domain

地址的 domain 部分。

addr_spec

地址的 username@domain 部分,正确引用以用作裸地址(上面显示的第二种形式)。 这个属性是不可变的。

__str__()

对象的 str 值是根据 RFC 5322 规则引用的地址,但没有任何非 ASCII 字符的内容传输编码。

为了支持 SMTP (RFC 5321),Address 处理一种特殊情况:如果 usernamedomain 都是空字符串(或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代表一个不在一个组中的地址。

addresses

一个可能为空的 Address 对象元组,表示组中的地址。

__str__()

Groupstr 值根据 RFC 5322 格式化,但没有任何非 ASCII 字符的内容传输编码。 如果 display_name 为 none 且 addresses 列表中有一个 Address,则 str 值将与 str 相同那个单Address

脚注

1
最初在 3.3 中作为 临时模块 添加