email.header:国际化标头

源代码: Lib/email/header.py


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

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

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

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

如果要在电子邮件标头中包含非 ASCII 字符,例如在 SubjectTo 字段中,则应使用 Header 类,并将 Message 对象中的字段分配给 Header 的实例,而不是使用字符串作为标头值。从 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 字符显示此标头。

这是 Header 类的描述

class email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')

创建一个符合 MIME 且可以包含不同字符集中字符串的标头。

可选的 s 是初始标头值。如果 None(默认值),则不设置初始标头值。您稍后可以使用 append() 方法调用追加到标头。s 可以是 bytesstr 的实例,但请参阅 append() 文档了解语义。

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

可以通过 maxlinelen 显式指定最大行长度。对于将第一行拆分为较短的值(以考虑未包含在 s 中的字段标头,例如 Subject),请传入 header_name 中的字段名称。默认的 maxlinelen 是 78,而 header_name 的默认值是 None,这意味着在长、拆分的标头的第一行中不考虑它。

可选的 continuation_ws 必须是符合 RFC 2822 的折叠空格,通常是空格或硬制表符。此字符将添加到延续行的前面。continuation_ws 默认为单个空格字符。

可选的 errors 会直接传递到 append() 方法。

append(s, charset=None, errors='strict')

将字符串 s 追加到 MIME 标头。

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

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

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

在任何一种情况下,当使用 RFC 2822 规则,生成符合 RFC 2047 规则的头部时,该字符串将使用字符集的输出编解码器进行编码。 如果字符串无法使用输出编解码器进行编码,则会引发 UnicodeError。

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

encode(splitchars=';, \t', maxlinelen=None, linesep='\n')

将消息头编码为符合 RFC 的格式,可能会包装长行,并将非 ASCII 部分封装在 base64 或 quoted-printable 编码中。

可选的 splitchars 是一个字符串,其中包含在正常头部包装期间应由拆分算法赋予额外权重的字符。 这非常粗略地支持 RFC 2822 的“更高级别的语法中断”:在行拆分期间优先选择以 splitchar 开头的拆分点,字符的优先级顺序与它们在字符串中出现的顺序相同。 可以在字符串中包含空格和制表符,以指示当其他拆分字符未出现在正在拆分的行中时,是否应优先将其中一个作为拆分点。 Splitchars 不会影响 RFC 2047 编码的行。

如果给定 maxlinelen,则会覆盖实例的最大行长度值。

linesep 指定用于分隔折叠头部行的字符。 它默认为 Python 应用程序代码中最有用的值 (\n),但可以指定 \r\n 以生成具有符合 RFC 的行分隔符的头部。

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

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

__str__()

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

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

__eq__(other)

此方法允许您比较两个 Header 实例是否相等。

__ne__(other)

此方法允许您比较两个 Header 实例是否不相等。

email.header 模块还提供了以下方便的函数。

email.header.decode_header(header)

解码消息头的值,而不转换字符集。头部值位于 header 中。

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

这是一个例子

>>> 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() 返回的成对序列创建 Header 实例。

decode_header() 接受头部值字符串并返回格式为 (decoded_string, charset) 的对序列,其中 charset 是字符集的名称。

此函数接受其中一个成对序列,并返回一个 Header 实例。可选的 maxlinelenheader_namecontinuation_wsHeader 构造函数中的相同。