:策略对象 – 电子邮件和MIME处理包(Python教程)(参考资料)
email.policy
:策略对象
版本3.3.
新增源代码: Lib / email / policy.py
email
包的主要关注的是处理各种电子邮件和MIME RFC所描述的电子邮件消息。但是,电子邮件消息的一般格式(一个标题字段块,每个字段包含一个名称后跟一个冒号后跟一个值,整个块后跟一个空行和一个’body’),是一种在电子邮件的境界。其中一些用途与主要的电子邮件RFC非常接近,有些则没有。即使在处理电子邮件时,有时也需要严格遵守RFC,例如生成与不符合标准的电子邮件服务器互操作的电子邮件,或者以违反标准的方式实施要使用的扩展.
策略对象使电子邮件包能够灵活处理所有已分离的用例.
A Policy
object封装了一组属性和方法,用于在使用期间控制电子邮件包的各个组件的行为.Policy
实例可以传递给电子邮件包中的各种类和方法以更改默认行为。可设置的值及其默认值如下所述.
电子邮件包中的所有类都使用默认策略。对于所有parser
类和相关的便利函数,以及Message
类,这是Compat32
策略,通过其相应的预定义实例compat32
。此策略提供与电子邮件包的Python3.3之前版本的完全向后兼容性(在某些情况下,包括执行兼容性).
policy关键字的默认值为EmailMessage
是EmailPolicy
策略,通过预定义的实例default
.
当创建一个Message
或EmailMessage
对象时,它获取一个策略。如果消息是由parser
,传递给解析器的策略将是它创建的消息使用的策略。如果消息是由程序创建的,则可以在创建策略时指定策略。当邮件传递给generator
,生成器默认使用消息中的策略,但您也可以将特定策略传递给生成器,该策略将覆盖存储在消息对象上的策略.
的默认值policy的关键字email.parser
类和解析器的便利功能会改变在未来的Python版本中。所以你应该在调用 module.parser
中描述的任何类和函数时,总是明确指定要使用的策略
本文档的第一部分介绍了Policy
,抽象基类的功能,它定义了所有策略对象共有的功能,包括compat32
。这包括由电子邮件包在内部调用的某些hook方法,自定义策略可以覆盖这些方法以获取不同的行为。第二部分描述了混凝土类EmailPolicy
和Compat32
,它们分别实现了提供标准行为和向后兼容行为和特征的钩子.
Policy
实例是不可变的,但它们可以克隆,接受相同的关键字参数作为类构造函数,并返回一个新的Policy
实例,它是原始的副本,但指定的属性值已更改.
例如,以下代码可以用于从磁盘上读取电子邮件并将其传递给系统sendmail
在Unix系统上编程:
>>> 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="rn"))>>> g.flatten(msg)>>> p.stdin.close()>>> rc = p.wait()
这里我们告诉BytesGenerator
使用RFC纠正线创建二进制字符串以输入sendmail"s
stdin
时的分隔符,默认策略将使用n
lineseparators.
一些电子邮件包方法接受policy关键字参数,允许为该方法覆盖策略。例如,下面的代码使用上一个示例中as_bytes()
对象的msg方法,并使用运行它的平台的本机lineseparator将消息写入文件:
>>> import os>>> with open("converted.txt", "wb") as f:... f.write(msg.as_bytes(policy=msg.policy.clone(linesep=os.linesep)))17
策略对象也可以使用加法运算符进行组合,生成apolicy对象,其设置是对象的非默认值的组合:
>>> compat_SMTP = policy.compat32.clone(linesep="rn")>>> 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_length80>>> apolicy = policy80 + policy100>>> apolicy.max_line_length400
- class
email.policy.
Policy
(**kw) -
对于所有策略类,这是抽象基类。它提供了几个简单方法的默认实现,以及不变性属性的实现,
clone()
方法和构造函数语义.策略类的构造函数可以传递各种关键字参数。可以指定的参数是此类的任何非方法属性,以及具体类上的任何其他非方法属性。构造函数中指定的Avalue将覆盖相应属性的默认值.
此类定义以下属性,因此可以在任何策略类的构造函数中传递以下值:
max_line_length
-
序列化输出中任何行的最大长度,不包括行尾字符。默认值为78,每 RFC 5322 。值
0
或None
表示根本没有换行.
linesep
-
用于终止序列化输出中的行的字符串。默认是
n
因为这是Python使用的内部行尾规则,但RFC需要rn
cte_type
-
控制可能或将要使用的内容传输编码的类型。可能的值是:
7bit
所有数据必须是“7位清洁”(仅限ASCII)。这意味着必要的数据将使用quoted-printable或base64编码进行编码. 8bit
data不限于7位清理。标题中的数据必须仅为ASCII,因此将被编码(参见 fold_binary()
和utf8
下面的forexceptions),但是正文部分可能会使用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中新增: mangle_from_参数
message_factory
-
用于构造新的空消息对象的工厂函数。在构建消息时由解析器使用。默认为
None
,在这种情况下Message
使用.新版本3.6.
以下
Policy
方法是使用电子邮件库通过代码调用以使用自定义设置创建策略实例:clone
(**kw)-
返回一个新的
Policy
实例,其属性具有相同的值当前实例,除非这些属性通过关键字arguments赋予新值.
剩余的
Policy
方法由电子邮件包代码调用,并不打算由使用的应用程序调用电子邮件包。自定义策略必须实现所有这些方法.handle_defect
(obj, defect)-
处理defect发现在obj。当电子邮件包调用thismethod时,defect将始终是
Defect
.的子类。默认实现检查
raise_on_defect
标志。如果是True
, defect被提出作为例外。如果是False
(默认),obj和defect传递给register_defect()
.
register_defect
(obj, defect)-
在defect上注册一个obj。在电子邮件包中,defect将永远是
Defect
.的子类。默认实现调用
append
defects
属性的obj方法。当电子邮件包调用handle_defect
,obj时通常会有defects
具有append
方法的属性。与电子邮件包一起使用的自定义对象类型(例如,自定义Message
对象)也应该提供这样的属性,否则解析的消息中的缺陷会引起意外错误.
header_max_count
(name)-
返回名为name.
将标题添加到
EmailMessage
或Message
对象时调用。如果返回的值不是0
或None
,并且已经有多个头文件名为name大于或等于返回的值,ValueError
被提升.因为
Message.__setitem__
是将值附加到标题列表,很容易创建重复标题而不实现它。这种方法允许某些标题被限制在该标题的实例数量中,可以添加到Message
编程。(解析器没有观察到这个限制,它将忠实地生成解析的消息中存在的多个头。)默认实现返回
None
所有标题名称.
header_source_parse
(sourcelines )-
电子邮件包使用字符串列表调用此方法,每个字符串都使用在被解析的源中找到的行分隔字符。第一行包括字段标题名称和分隔符。源中的所有空格都被保留。该方法应该返回
(name, value)
将要存储在Message
中的元组来表示已解析的标题.如果实现希望保持与现有邮件包策略的兼容性,name应该是案例保留的名称(所有字符直到’
:
‘分隔符),而value应该是展开的值(删除所有行分隔符,但空格键完整),去掉前导空格.sourcelines可能包含代理二进制数据.
没有默认实现
header_store_parse
(name, value)-
当应用程序修改
Message
以编程方式(而不是由aparser创建的Message
)。该方法应返回(name, value)
元组,该元组将存储在Message
中以表示标题.如果实现希望保持与现有邮件包策略的兼容性,则name和value应该是字符串orstring子类,不会改变传递的参数的内容.
没有默认的实现
header_fetch_parse
(name, value)-
电子邮件包调用此方法时,name和value目前存放在
Message
当应用程序请求该标头时,无论方法返回什么,都将作为要检索的标头的值传回给应用程序。请注意,中可能存在多个具有相同名称的标头Message
;该方法传递了指向要返回给应用程序的头的特定名称和值.value可能包含代理二进制数据。方法返回的值应该有nosurrogateescaped二进制数据.
没有默认实现
fold
(name, value)-
电子邮件包调用此方法时,name和value目前存放在
Message
对于给定的标题。该方法应该通过将name与value组合并插入linesep
在适当的地方的字符。请参阅 RFC 5322 讨论折叠电子邮件标题的规则.value可能包含代理二进制数据。在方法返回的字符串中应该有nosurrogateescaped二进制数据.
fold_binary
(name, value)-
和
fold()
,除了返回的值应该是abytes对象而不是字符串.value可能包含代理二进制数据。这些可以转换回返回的字节对象中的二进制数据.
- class
email.policy.
EmailPolicy
(**kw) -
这个具体的
Policy
提供旨在完全符合当前电子邮件RFC的行为。这些包括(但不限于) RFC 5322 , RFC 2047 ,以及当前的MIME RFCs.此策略添加了新的头解析和折叠算法。而不是简单的字符串,标题是
str
具有依赖于字段类型的属性的子类。解析和折叠算法完全实现 RFC 2047 和 RFC 5322 .message_factory
attribute是EmailMessage
.除了上面列出的适用于allpolicies的可设置属性之外,此策略还添加了以下附加属性:
版本3.6中新增: [1]
utf8
-
如果
False
,按照 RFC 5322 ,通过将它们编码为“编码的单词”来支持非ASCII字符。如果True
,请按照 RFC 6532 并使用utf-8
编码标题。以这种方式格式化的消息可以传递给支持SMTPUTF8
扩展的SMTP服务器( RFC 6531 ).
refold_source
-
如果是
Message
对象起源于parser
(与程序设置相反),thisattribute指示生成器在将消息转换回序列化形式时是否应该重新折叠该值。可能的值是:none
所有源值都使用原始折叠 long
有任何超过 max_line_length
的行的源值将被重新折叠all
所有值都是refoldded . 默认是
long
.
header_factory
-
一个可调用的,有两个参数,
name
和value
,其中name
是头字段名称,value
是展开的头字段值,并返回表示该头的字符串子类。Adefaultheader_factory
(见headerregistry
)提供支持自定义解析各种地址和日期 RFC 5322 标头字段类型和主要MIME标头字段stypes。将来会添加支持有条件的自定义解析.
content_manager
-
具有至少两个方法的对象:get_content和set_content。
get_content()
或set_content()
EmailMessage
调用对象,它调用此对象的相应方法,将消息对象作为其第一个参数传递给它,并将任何传递给它的参数或关键字作为附加参数传递给它。默认情况下content_manager
被设置为raw_data_manager
.版本3.4.
该类提供了
Policy
:header_max_count
(name)-
返回
max_count
用于表示具有给定名称的标题的专用类的属性.
header_source_parse
(sourcelines)-
该名称被解析为“
:
”并返回修改后的所有内容。通过从第一行的剩余部分剥离前导空格,将所有后续行连接在一起,并剥离任何尾随回车符或换行符来确定该值.
header_store_parse
(name, value)-
名称未更改。如果输入值具有
name
属性且匹配name忽略大小写,则返回值。否则将name和value传递给header_factory
,并将结果头对象作为值返回。在这种情况下,如果输入值包含CR或LF字符,则会引发ValueError
.
header_fetch_parse
(name, value)-
如果值为
name
属性,它返回到未修改。否则name和value与任何CR或LF字符被删除,传递给header_factory
,并且resultheader对象是回。任何代理字节转换为unicode unknown-character glyph.
fold
(name, value)-
头部折叠由
refold_source
策略设置。如果和,则值被视为“源值”只有它没有name
属性(具有name
属性意味着它是某种类型的头对象)。如果需要根据策略重新链接源值,则会将其转换为绕过name并且value将任何CR和LF字符移除到header_factory
。通过使用当前策略调用其fold
方法来完成对标题对象的折叠.使用
splitlines()
将源值拆分为行。如果不重新折叠该值,则使用linesep
从政策和返回。例外是包含非ascii二进制数据的行。在这种情况下,重新折叠值,无论refold_source
设置,导致二进制数据使用unknown-8bit
charset.
fold_binary
(name, value)-
进行CTE编码。与
fold()
相同cte_type
是7bit
,除了返回的值是bytes.如果
cte_type
是8bit
,非ASCII二进制数据被转换回字节。无论refold_header
设置,因为无法知道二进制数据是由单字节字符还是多字节字符组成.
以下EmailPolicy
提供适用于特定应用程序域的默认值。注意以后这些实例的行为(特别是HTTP
实例)可以进行调整,以便更紧密地符合与其域相关的RFC .
email.policy.
default
-
一个
EmailPolicy
的实例,所有默认值都保持不变。此策略使用标准Pythonn
行结尾而不是RFC纠正rn
.
email.policy.
SMTP
-
适合按照电子邮件RFCs.Like
default
序列化邮件,但是linesep
设置为rn
,这是RFCcompliant。
email.policy.
SMTPUTF8
-
和
SMTP
除了utf8
是True
。用于将消息序列化到消息存储库而不使用标头中的编码字。如果这些地址或收件人地址具有非ASCII字符(smtplib.SMTP.send_message()
方法自动处理),则只能用于SMTP传输.
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
获取标题值导致正在解析的标题和标题对象创造和回复.- 任何头对象或由于策略设置而重新折叠的任何头都使用完全实现RF折叠算法的算法折叠,包括知道需要和允许编码字的位置.
从应用程序视图,这意味着通过EmailMessage
获得的任何头是带有extraattributes的头对象,其字符串值是头的完全解码的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)-
名称和值未经修改返回.
header_fetch_parse
(name, value)-
如果值包含二进制数据,则将其转换为
Header
对象使用unknown-8bit
charset.Otherwise它未经修改地返回.
fold
(name, value)-
使用
Header
foldalgorithm,它保留值中的现有换行符,并将结果行包装到max_line_length
。非ASCII二进制数据是使用unknown-8bit
charset进行CT编码的
fold_binary
/name, value/-
//使用
Header
折叠算法折叠头部,它保留了值中现有的换行符,并将结果行包装到max_line_length
。如果cte_type
是7bit
,则使用unknown-8bit
字符集对非ascii二进制数据进行CTE编码。否则使用原始源头,其现有的行中断和它可能包含的任何(RFC无效)二进制数据.
email.policy.
compat32
-
Compat32
的实例,提供与电子邮件包的行为的向后兼容性Python 3.2.
Footnotes
[1] | 在3.3中作为临时特征添加了. |