# 19.1。 `email` - 电子邮件和MIME处理包

源代码： Lib / email / __ init __。py

`email`包是用于管理电子邮件（包括MIME和其他 RFC 2822的邮件文档）的库。具体来说，不是旨在向SMTP（ RFC 2821），NNTP或其他服务器发送任何电子邮件；那些是诸如`smtplib`和`nntplib`之类的模块的功能。The `email` package attempts to be as RFC-compliant as possible, supporting in addition to RFC 2822, such MIME-related RFCs as RFC 2045, RFC 2046, RFC 2047, and RFC 2231.

`email`包的主要区别功能是它分割来自内部对象模型电子邮件表示的电子邮件消息的解析和生成。使用`email`包的应用程序主要处理对象；您可以向消息添加子对象，从消息中删除子对象，完全重新排列内容等。有一个单独的解析器和一个单独的生成器处理从平面文本到对象模型的转换，然后再回到平面文本。对于一些常见的MIME对象类型，还有一些方便的子类，以及一些杂项实用程序，它们帮助提取和解析消息字段值，创建符合RFC的日期等常见任务。

以下部分描述了`email`包的功能。排序遵循应用中常见的进展：电子邮件消息从文件或其他源读取为平面文本，解析文本以产生电子邮件消息的对象结构，操纵该结构，最后，对象树被渲染回平面文本。

用完整的布料制造物体结构是完全可行的。完全从头开始。从那里，可以采取与上面类似的进展。

还包括`email`包提供的所有类和模块的详细规范，使用`email`包时可能遇到的异常类，一些辅助实用程序和几个例子。对于旧版`mimelib`包或`email`包的早期版本的用户，提供了有关差异和移植的部分。

`email`包文档的内容：

- 19.1.1. `email.message`：表示电子邮件
- 19.1.2. `email.parser`：解析电子邮件
  - 19.1.2.1. FeedParser API
  - 19.1.2.2.解析器类API
  - 19.1.2.3.其他注意事项
- 19.1.3. `email.generator`：生成MIME文档
- 19.1.4. `email.policy`：Policy Objects
- 19.1.5. `email.headerregistry`：自定义标题对象
- 19.1.6. `email.contentmanager`：管理MIME内容
  - 19.1.6.1.内容管理器实例
- 19.1.7. `email.mime`：从头开始创建电子邮件和MIME对象
- 19.1.8. `email.header`：国际化标头
- 19.1.9. `email.charset`：表示字符集
- 19.1.10. `email.encoders`：Encoders
- 19.1.11. `email.errors`：异常和缺陷类
- 19.1.12. `email.utils`：其他实用程序
- 19.1.13. `email.iterators`：Iterators
- 19.1.14. `email`：示例
  - 19.1.14.1.使用临时API的示例

也可以看看

模块`smtplib`
  SMTP协议客户端
模块`nntplib`
  NNTP协议客户端

## 19.1.15. 包历史

此表描述了电子邮件包的发布历史记录，对应于软件包发布的Python版本。为了本文档的目的，当您看到有关更改或添加的版本的说明时，这些更改是指在电子邮件包版本中进行的更改，而不是。此表还描述了每个版本的软件包的Python兼容性。

电子邮件版本 | 分布式 | 兼容
--- | --- | ---
`1.x` | Python 2.2.0到Python 2.2.1 | 不再支持
`2.5` | Python 2.2.2+和Python 2.3 | Python 2.1到2.5
`3.0` | Python 2.4和Python 2.5 | Python 2.3到2.6
`4.0` | Python 2.5到Python 2.7 | Python 2.3到2.7
`5.0` | Python 3.0和Python 3.1 | Python 3.0到3.2
`5.1` | Python 3.2 | Python 3.2

5.1版之后（Python 3.2），电子邮件包不再具有与Python版本分开的版本。（有关更改的详细信息，请参阅各个Python版本的What’s New in Python文档。）

以下是`email`版本5.1和版本5.0之间的主要区别：

- 可以再次解析包含非ASCII字节的消息，并且如果包含非ASCII字节的数据未被修改，则再现这样的消息。
- 新功能`message_from_bytes()`和`message_from_binary_file()`和新类`BytesFeedParser`和`BytesParser`允许二进制消息数据解析为模型对象。
- 给定模型输入的字节，`get_payload()`将默认使用`8bit`来解码具有内容传输编码的消息体在MIME头中指定的字符集，并返回结果字符串。
- 给定模型的输入字节，`Generator`将转换具有8位的内容传输编码的消息体，而是具有7位内容传输编码。
- 新类`BytesGenerator`生成字节作为输出，保留用于构建模型的输入中存在的任何未更改的非ASCII数据，包括具有内容传输编码 t3 > 8bit。

以下是`email`版本5.0和版本4之间的主要区别：

- 所有操作都在Unicode字符串上。文本输入必须是字符串，文本输出是字符串。输出限于ASCII字符集，因此可以编码为ASCII用于传输。输入也限于ASCII；这是一个公认的电子邮件5.0的限制，意味着它只能用于解析7bit干净的电子邮件。

以下是`email`版本4和版本3之间的主要区别：

- 所有模块已根据 PEP 8标准重命名。例如，版本3模块`email.Message`在版本4中已重命名为`email.message`。

- 添加了新的子包`email.mime`，并且所有版本3 `email.MIME*`模块已重命名并位于`email.mime`子包中。例如，版本3模块`email.MIMEText`已重命名为`email.mime.text`。

  请注意，版本3名称将继续工作，直到Python 2.6。

- 添加了`email.mime.application`模块，其中包含`MIMEApplication`类。

- 已在版本3中弃用的方法已删除。这些包括`Generator.__call__()`，`Message.get_type()`，`Message.get_main_type()`，`Message.get_subtype()`。

- 为 RFC 2231支持添加了修正，可以更改`Message.get_param`和朋友的一些返回类型。在某些情况下，用于返回3元组的值现在返回简单字符串（具体来说，如果所有扩展参数段都未编码，则不需要指定语言和字符集，因此返回类型现在是一个简单的字符串）。另外，％编码用于对编码和非编码段进行；现在仅对编码的段进行这种解码。

以下是`email`版本3和版本2之间的主要区别：

- 引入了`FeedParser`类，并且`FeedParser`中实现了`Parser`类。因此，所有解析都是非严格的，解析将尽最大努力不要引发异常。解析邮件时发现的问题存储在邮件的defect属性中。
- 删除了在版本2中生成`DeprecationWarning`的API的所有方面。These include the _encoder argument to the `MIMEText` constructor, the `Message.add_payload()` method, the `Utils.dump_address_pair()` function, and the functions `Utils.decode()` and `Utils.encode()`.
- New `DeprecationWarning`s have been added to: `Generator.__call__()`, `Message.get_type()`, `Message.get_main_type()`, `Message.get_subtype()`, and the strict argument to the `Parser` class. 这些都将在未来的版本中删除。
- 支持早于2.3的Pythons已删除。

以下是`email`版本2和版本1之间的差异：

- 已添加`email.Header`和`email.Charset`模块。

- `Message`实例的pickle格式已更改。由于这是从来没有（仍然没有）正式定义，这不被认为是一个向后的不兼容性。但是，如果您的应用程序选择并取消选择`Message`实例，请注意在`email`版本2中，`Message`实例现在具有专用变量_charset 和_default_type。

- `Message`类中的几个方法已被弃用，或者它们的签名已更改。此外，还增加了许多新的方法。有关详细信息，请参阅`Message`类的文档。更改应该完全向后兼容。

- 面对message / rfc822内容类型，对象结构已更改。在`email`版本1中，这种类型将由标量有效载荷表示，即容器消息的`is_multipart()`返回false，`get_payload()`不是列表对象，而是单个`Message`

  此结构与程序包的其余部分不一致，因此更改了message / rfc822内容类型的对象表示。In `email` version 2, the container does return `True` from `is_multipart()`, and `get_payload()` returns a list containing a single `Message` item.

  注意，这是一个不能完全保持向后兼容性的地方。但是，如果您已经测试了`get_payload()`的返回类型，则应该没问题。您只需要确保您的代码不会对内容类型为message / rfc822的容器执行`set_payload()`和`Message` t6>。

- 添加了`Parser`构造函数的strict参数，并且它的`parse()`和`parsestr()`方法增长了 headersonly参数。strict标记也已添加到函数`email.message_from_file()`和`email.message_from_string()`中。

- `Generator.__call__()`已弃用；请使用`Generator.flatten`。`Generator`类也生长了`clone()`方法。

- 添加了`email.generator`模块中的`DecodedGenerator`类。

- 已添加中间基类`MIMENonMultipart`和`MIMEMultipart`，并插入到大多数其他MIME相关派生类的类层次结构中。

- `MIMEText`构造函数的_encoder参数已被弃用。现在，基于_charset参数隐式地进行编码。

- `email.Utils`模块中的以下函数已弃用：`dump_address_pairs()`，`decode()`和`encode()`以下函数已添加到模块：`make_msgid()`，`decode_rfc2231()`，`encode_rfc2231()`和`decode_params()`。

- 已添加非公开函数`email.Iterators._structure()`。

## 19.1.16. 与`mimelib` 的区别

`email`包最初原型化为一个名为mimelib的独立库。已进行更改，以使方法名称更加一致，并且已添加或删除一些方法或模块。一些方法的语义也改变了。在大多数情况下，`mimelib`中提供的任何功能在`email`包中仍然可用，但通常采用不同的方式。`mimelib`包与`email`包之间的向后兼容性不是优先级。

以下简要说明`mimelib`和`email`包之间的区别，以及如何移植应用程序的提示。

当然，两个包之间最明显的区别是包名称已更改为`email`。此外，顶级包具有以下区别：

- `messageFromString()`已重命名为`message_from_string()`。
- `messageFromFile()`已重命名为`message_from_file()`。

`Message`类有以下区别：

- 方法`asString()`已重命名为`as_string()`。
- 方法`ismultipart()`已重命名为`is_multipart()`。
- `get_payload()`方法已生成解码可选参数。
- 方法`getall()`已重命名为`get_all()`。
- 方法`addheader()`已重命名为`add_header()`。
- 方法`gettype()`已重命名为`get_type()`。
- 方法`getmaintype()`已重命名为`get_main_type()`。
- 方法`getsubtype()`已重命名为`get_subtype()`。
- 方法`getparams()`已重命名为`get_params()`。此外，`getparams()`返回字符串列表，`get_params()`返回一个2元组列表，实际上参数的键/ `'='`符号。
- 方法`getparam()`已重命名为`get_param()`。
- 方法`getcharsets()`已重命名为`get_charsets()`。
- 方法`getfilename()`已重命名为`get_filename()`。
- 方法`getboundary()`已重命名为`get_boundary()`。
- 方法`setboundary()`已重命名为`set_boundary()`。
- 方法`getdecodedpayload()`已删除。要获得类似的功能，请将值1传递给`get_payload()`方法的decode标志。
- 方法`getpayloadastext()`已删除。类似的功能由`email.generator`模块中的`DecodedGenerator`类支持。
- 方法`getbodyastext()`已删除。您可以通过在`email.iterators`模块中创建`typed_subpart_iterator()`的迭代器来获得类似的功能。

`Parser`类在其公共接口中没有差异。它有一些额外的智能识别消息/交付状态类型消息，它表示为`Message`实例包含单独的`Message`子部分传送状态通知[1]中的标题块。

`Generator`类在其公共接口上没有差异。在`email.generator`模块中有一个新类，名为`DecodedGenerator`，它提供了以前在`Message.getpayloadastext()`

以下模块和类已更改：

- `MIMEBase`类构造函数参数_major和_minor分别更改为_maintype和_subtype 。

- `Image`类/模块已重命名为`MIMEImage`。_minor参数已重命名为_subtype。

- `Text`类/模块已重命名为`MIMEText`。_minor参数已重命名为_subtype。

- `MessageRFC822`类/模块已重命名为`MIMEMessage`。请注意，`mimelib`的早期版本称为此类/模块`RFC822`，但是与某些不区分大小写的Python标准库模块`rfc822`文件系统。

  此外，`MIMEMessage`类现在表示主类型为消息的任何类型的MIME消息。它采用可选参数_subtype，用于设置MIME子类型。_subtype默认为rfc822。

`mimelib`在其`address`和`date`模块中提供了一些实用程序函数。所有这些功能都已移至`email.utils`模块。

`MsgReader`类/模块已删除。其功能在`email.iterators`模块中的`body_line_iterator()`函数中得到最密切支持。

脚注

[1] T0> | 传递状态通知（DSN）在 RFC 1894中定义。