# `email.contentmanager`: 管理 MIME 内容

源代码: Lib/email/contentmanager.py

3.6 新版功能: 1

class `email.contentmanager.``ContentManager`

  内容管理器的基类。 提供注册 MIME 内容和其他表示形式间转换器的标准注册机制，以及 `get_content` 和 `set_content` 发送方法。

  `get_content`(msg, *args, **kw)

    基于 msg 的 `mimetype` 查找处理函数（参见下一段），调用该函数，传递所有参数，并返回调用的结果。 期望的效果是处理程序将从 msg 中提取有效载荷并返回编码了有关被提取数据信息的对象。

    要找到处理程序，将在注册表中查找以下键，找到第一个键即停止:

    > - 表示完整 MIME 类型的字符串 (`maintype/subtype`)

    > - 表示 `maintype` 的字符串

    > - 空字符串

    如果这些键都没有产生处理程序，则为完整 MIME 类型引发一个 `KeyError`。

  `set_content`(msg, obj, *args, **kw)

    如果 `maintype` 为 `multipart`，则引发 `TypeError`；否则基于 obj 的类型（参见下一段）查找处理函数，在 msg 上调用 `clear_content()`，并调用处理函数，传递所有参数。 预期的效果是处理程序将转换 obj 并存入 msg，并可能对 msg 进行其他更改，例如添加各种 MIME 标头来编码需要用来解释所存储数据的信息。

    要找到处理程序，将获取 obj 的类型 (`typ = type(obj)`)，并在注册表中查找以下键，找到第一个键即停止:

    > - 类型本身 (`typ`)

    > - 类型的完整限定名称 (`typ.__module__ + '.' + typ.__qualname__`)。

    > - 类型的 qualname (`typ.__qualname__`)

    > - 类型的 name (`typ.__name__`)。

    如果未匹配到上述的任何一项，则在 MRO (`typ.__mro__`) 中为每个类型重复上述的所有检测。 最后，如果没有其他键产生处理程序，则为 `None` 键检测处理程序。 如果也没有 `None` 的处理程序，则为该类型的完整限定名称引发 `KeyError`。

    并会添加一个 MIME-Version 标头，如果没有的话 (另请参见 `MIMEPart`)。

  `add_get_handler`(key, handler)

    将 handler 函数记录为 key 的处理程序。 对于可能的 key 键，请参阅 `get_content()`。

  `add_set_handler`(typekey, handler)

    将 handler 记录为当一个匹配 typekey 的类型对象被传递给 `set_content()` 时所要调用的函数。 对于可能的 typekey 值，请参阅 `set_content()`。

## 内容管理器实例

目前 email 包只提供了一个实体内容管理器 `raw_data_manager`，不过在未来可能会添加更多。 `raw_data_manager` 是由 `EmailPolicy` 及其衍生工具所提供的 `content_manager`。

`email.contentmanager.``raw_data_manager`

  这个内容管理器仅提供了超出 `Message` 本身提供内容的最小接口：它只处理文本、原始字节串和 `Message` 对象。 不过相比基础 API，它具有显著的优势：在文本部分上执行 `get_content` 将返回一个 unicode 字符串而无需由应用程序来手动解码，`set_content` 为控制添加到一个部分的标头和控制内容传输编码格式提供了丰富的选项集合，并且它还启用了多种 `add_` 方法，从而简化了多部分消息的创建过程。

  `email.contentmanager.``get_content`(msg, errors='replace')

    将指定部分的有效载荷作为字符串（对于 `text` 部分）, `EmailMessage` 对象（对于 `message/rfc822` 部分）或 `bytes` 对象（对于所有其他非多部分类型）返回。 如果是在 `multipart` 上调用则会引发 `KeyError`。 如果指定部分是一个 `text` 部分并且指明了 errors，则会在将载荷解码为 unicode 时将其用作错误处理程序。 默认的错误处理程序是 `replace`。

  `email.contentmanager.``set_content`(msg, <'str'>, subtype="plain", charset='utf-8', cte=None, disposition=None, filename=None, cid=None, params=None, headers=None)
  `email.contentmanager.``set_content`(msg, <'bytes'>, maintype, subtype, cte="base64", disposition=None, filename=None, cid=None, params=None, headers=None)
  `email.contentmanager.``set_content`(msg, <'EmailMessage'>, cte=None, disposition=None, filename=None, cid=None, params=None, headers=None)

    向 msg 添加标头和有效载荷:

    添加一个带有 `maintype/subtype` 值的 Content-Type 标头。

    > - 对于 `str`，将 MIME `maintype` 设为 `text`，如果指定了子类型 subtype 则设为指定值，否则设为 `plain`。

    > - 对于 `bytes`，将使用指定的 maintype 和 subtype，如果未指定则会引发 `TypeError`。

    > - 对于 `EmailMessage` 对象，将 maintype 设为 `message`，并将指定的 subtype 设为 subtype，如果未指定则设为 `rfc822`。 如果 subtype 为 `partial`，则引发一个错误（必须使用 `bytes` 对象来构造 `message/partial` 部分）。

    如果提供了 charset (这只对 `str` 适用)，则使用指定的字符集将字符串编码为字节串。 默认值为 `utf-8`。 如果指定的 charset 是某个标准 MIME 字符集名称的已知别名，则会改用该标准字符集。

    If cte is set, encode the payload using the specified content transfer encoding, and set the Content-Transfer-Encoding header to that value. Possible values for cte are `quoted-printable`, `base64`, `7bit`, `8bit`, and `binary`. If the input cannot be encoded in the specified encoding (for example, specifying a cte of `7bit` for an input that contains non-ASCII values), raise a `ValueError`.

    > - For `str` objects, if cte is not set use heuristics to determine the most compact encoding.

    > - For `EmailMessage`, per RFC 2046, raise an error if a cte of `quoted-printable` or `base64` is requested for subtype `rfc822`, and for any cte other than `7bit` for subtype `external-body`. For `message/rfc822`, use `8bit` if cte is not specified. For all other values of subtype, use `7bit`.

    注解

    A cte of `binary` does not actually work correctly yet. The `EmailMessage` object as modified by `set_content` is correct, but `BytesGenerator` does not serialize it correctly.

    If disposition is set, use it as the value of the Content-Disposition header. If not specified, and filename is specified, add the header with the value `attachment`. If disposition is not specified and filename is also not specified, do not add the header. The only valid values for disposition are `attachment` and `inline`.

    If filename is specified, use it as the value of the `filename` parameter of the Content-Disposition header.

    If cid is specified, add a Content-ID header with cid as its value.

    If params is specified, iterate its `items` method and use the resulting `(key, value)` pairs to set additional parameters on the Content-Type header.

    If headers is specified and is a list of strings of the form `headername: headervalue` or a list of `header` objects (distinguished from strings by having a `name` attribute), add the headers to msg.

备注

1

  最初在 3.4 中作为 暂定模块 添加