email.header:国际化标题

源代码: Lib/email/header.py


此模块是旧版(Compat32)电子邮件 API 的一部分。在当前的 API 中,Headers 的编码和解码由EmailMessage类的类似于字典的 API 透明地处理。除了在旧代码中使用外,此模块还可用于需要完全控制在编码 Headers 时使用的字符集的应用程序。

本节中的其余文本是该模块的原始文档。

RFC 2822是描述电子邮件格式的基本标准。它源自较旧的 RFC 822标准,该标准在大多数电子邮件仅由 ASCII 字符组成的时候被广泛使用。 RFC 2822是假设电子邮件仅包含 7 位 ASCII 字符而编写的规范。

当然,随着电子邮件在 Global 范围内的部署,它已经国际化,因此特定于语言的字符集现在可以在电子邮件中使用。基本标准仍然要求仅使用 7 位 ASCII 字符传输电子邮件,因此编写了一系列 RFC,描述了如何将包含非 ASCII 字符的电子邮件编码为 RFC 2822兼容格式。这些 RFC 包括 RFC 2045 RFC 2046 RFC 2047 RFC 2231email软件包的email.headeremail.charset模块支持这些标准。

如果要在电子邮件标题中包含非 ASCII 字符,例如在* Subject To *字段中,则应使用Header类并将Message对象中的字段分配给Header的实例,而不要使用字符串 Headers 值。从email.header模块导入Header类。例如:

>>> 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 字符的?为此,我们创建了一个Header实例,并传入了用于编码字节字符串的字符集。当对随后的Message实例进行展平时, Subject *字段已正确进行 RFC 2047编码。支持 MIME 的邮件阅读器将使用嵌入式 ISO-8859-1 字符显示此 Headers。

这是Header类的描述:

    • class * email.header. Header(* s = None charset = None maxlinelen = None header_name = None continuation_ws ='' errors ='strict'*)
    • 创建一个 MIME 兼容的 Headers,其中可以包含不同字符集的字符串。

可选* s *是初始 Headers 值。如果为None(默认值),则不设置初始 Headers 值。您以后可以使用append()方法调用将其追加到标题中。 * s *可能是bytesstr的实例,但有关语义,请参见append()文档。

可选的* charset 有两个用途:它与append()方法的 charset 参数具有相同的含义。它还为所有Ellipsis charset 参数的后续append()调用设置默认字符集。如果构造函数中未提供 charset (默认值),则us-ascii字符集既用作 s *的初始字符集,又用作后续append()调用的默认字符集。

最大行长可以pass* maxlinelen 明确指定。为了将第一行拆分为较短的值(以说明 s 中未包含的字段标题,例如 Subject ),请在 header_name *中传递字段名称。 * maxlinelen 的默认值为 76,而 header_name *的默认值为None,这意味着较长的拆分标题的第一行未将其考虑在内。

可选* continuation_ws *必须是 RFC 2822兼容的折叠空白,并且通常是空格或硬制表符。该字符将添加到续行之前。 * continuation_ws *默认为单个空格字符。

可选的* errors *直接传递给append()方法。

  • append(* s charset = None errors ='strict'*)
    • 将字符串* s *附加到 MIMEHeaders。

可选的* charset (如果提供)应该是Charset实例(请参见email.charset)或字符集的名称,它将转换为Charset实例。值None(默认值)表示使用了构造函数中指定的 charset *。

  • s 可以是bytesstr的实例。如果它是bytes的实例,则 charset *是该字节字符串的编码,如果无法使用该字符集对该字符串进行解码,则将引发UnicodeError

如果* s str的实例,则 charset *是一个提示,指定字符串中字符的字符集。

无论哪种情况,当使用 RFC 2047规则生成 RFC 2822兼容的 Headers 时,都将使用字符集的输出编解码器对字符串进行编码。如果无法使用输出编解码器对字符串进行编码,则会引发 UnicodeError。

如果* s 是字节字符串,则将可选的 errors *作为 errors 参数传递给解码调用。

  • encode(* splitchars ='; t' maxlinelen = None linesep =' n'*)
    • 将消息 Headers 编码为符合 RFC 的格式,可能会包裹长行,并以 base64 或带引号的可编码形式封装非 ASCII 部分。

可选的* splitchars *是一个包含字符的字符串,在正常的 Headers 换行过程中,拆分算法应为这些字符串赋予额外的权重。这是对 RFC 2822的“高级句法break”的非常粗略的支持:在行分割期间,首选以 splitchar 开头的分割点,并且在字符串中出现的 Sequences 优选字符。字符串中可以包含空格和制表符,以指示当其他拆分字符未出现在要拆分的行中时,是否应优先选择另一个作为拆分点。 Splitchars 不会影响 RFC 2047个编码行。

  • maxlinelen *(如果指定)会覆盖实例的最大行长值。

  • linesep *指定用于分隔折叠标题行的字符。它默认为 Python 应用程序代码(\n)最有用的值,但是可以指定\r\n以便生成带有 RFC 兼容行分隔符的 Headers。

在版本 3.2 中进行了更改:添加了* linesep *参数。

Header类还提供了许多支持标准运算符和内置函数的方法。

  • __str__ ( )
    • 使用无限的行长,返回Header作为字符串的近似值。所有片段均使用指定的编码转换为 unicode,并适当地连接在一起。使用'replace'错误处理程序,会将任何具有'unknown-8bit'字符集的片段解码为 ASCII。

在版本 3.2 中进行了更改:添加了对'unknown-8bit'字符集的处理。

  • __eq__(其他)

    • 此方法使您可以比较两个Header实例的相等性。
  • __ne__(其他)

    • 此方法使您可以比较两个Header实例的不平等性。

email.header模块还提供以下便捷Function。

  • email.header. decode_header(* header *)
    • 解码消息头值,而不转换字符集。Headers 值在* header *中。

此函数返回一个(decoded_string, charset)对的列表,其中包含头的每个解码部分。 * charset *对于标题的未编码部分为None,否则为小写字符串,其中包含在编码字符串中指定的字符集的名称。

这是一个例子:

>>> 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()接收 Headers 值字符串,并返回一系列格式为(decoded_string, charset)的对,其中* charset *是字符集的名称。

此函数采用这些对中的一个序列并返回Header实例。可选的* maxlinelen header_name continuation_ws *与Header构造函数相同。