"email.contentmanager": 管理 MIME 内容
**************************************

**源代码:** Lib/email/contentmanager.py

======================================================================

Added in version 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 字符集名称的已知别名，则会改用该标准字符集。

      如果设置了 *cte*，则使用指定的内容传输编码格式对有效载荷进行编码
      ，并将 *Content-Transfer-Encoding* 标头设为该值。可能的 *cte* 值
      有 "quoted-printable", "base64", "7bit", "8bit" 和 "binary"。如
      果输入无法以指定的编码格式被编码（例如，对于包含非 ASCII 值的输
      入指定 *cte* 值为 "7bit")，则会引发 "ValueError"。

      * 对于 "str" 对象，如果未设置 *cte* 则使用启发式方法来确定最紧凑
        的编码格式。在编码之前，将使用 "str.splitlines()" 来正规化所有
        行边界，确保载荷的每一行是以当前策略的 "linesep" 属性来结束的
        （即使原始字符串不是以它结束）。

      * 对于 "bytes" 对象，如果未设置 *cte* 则使用 base64，并且不会执
        行之前提及的换行符转写。

      * 对于 "EmailMessage"，按照 **RFC 2046**，如果为 *subtype*
        "rfc822" 请求的 *cte* 为 "quoted-printable" 或 "base64"，或为
        *subtype* "external-body" 请求 "7bit" 以外的任何 *cte*，则会引
        发一个错误。对于 "message/rfc822"，如果 *cte* 未指定则会使用
        "8bit"。对于所有其他 *subtype* 值，都会使用 "7bit"。

      备注:

        *cte* 值为 "binary" 实际上还不能正确工作。由 "set_content" 所
        修改的 "EmailMessage" 对象是正确的，但 "BytesGenerator" 不会正
        确地将其序列化。

      如果设置了 *disposition*，它会被用作 *Content-Disposition* 标头
      的值。 如果未设置，并且指定了 *filename*，则添加值为
      "attachment" 的标头。如果未设置 *disposition* 并且也未指定
      *filename*，则不添加标头。 *disposition* 的有效值仅有
      "attachment" 和 "inline"。

      如果设置了 *filename*，则将其用作 *Content-Disposition* 标头的
      "filename" 参数的值。

      如果设置了 *cid*，则添加一个 *Content-ID* 标头并将其值设为 *cid*
      。

      如果设置了 *params*，则迭代其 "items" 方法并使用输出的 "(key,
      value)" 结果对在 *Content-Type* 标头上设置附加参数。

      如果设置了 *headers* 并且为 "headername: headervalue" 形式的字符
      串的列表或为 "header" 对象的列表（通过一个 "name" 属性与字符串相
      区分），则将标头添加到 *msg*。

-[ 脚注 ]-

[1] 最初在 3.4 中作为 *暂定模块* 添加
