18.10. multifile — 支持包含不同部分的文件 — Python 文档

来自菜鸟教程
Python/docs/2.7/library/multifile
跳转至:导航、​搜索

18.10. 多文件 — 支持包含不同部分的文件

自 2.5 版起已弃用:email 包应优先于 multifile 模块使用。 该模块的存在只是为了保持向后兼容性。


MultiFile 对象使您能够将文本文件的部分视为类似文件的输入对象,当给定的分隔符模式为 readline() 时, 将返回遭遇。 此类的默认值旨在使其可用于解析 MIME 多部分消息,但通过将其子类化并覆盖方法,它可以轻松适应更广泛的用途。

class multifile.MultiFile(fp[, seekable])

创建一个多文件。 您必须使用 MultiFile 实例的输入对象参数实例化此类以从中获取行,例如由 open() 返回的文件对象。

MultiFile 只查看输入对象的 readline()seek()tell() 方法,后两个是仅当您想要随机访问各个 MIME 部分时才需要。 要在不可搜索的流对象上使用 MultiFile,请将可选的 seekable 参数设置为 false; 这将阻止使用输入对象的 seek()tell() 方法。

知道在 MultiFile 的世界观中,文本由三种行组成:数据、节分隔符和结束标记,这将是有用的。 MultiFile 旨在支持解析可能具有多个嵌套消息部分的消息,每个部分都有自己的节分隔符和结束标记行模式。

也可以看看

模块电子邮件
全面的电子邮件处理包; 取代 multifile 模块。


18.10.1. 多文件对象

MultiFile 实例具有以下方法:

MultiFile.readline(str)
读一行。 如果该行是数据(不是节分隔符或结束标记或真正的 EOF),则返回它。 如果该行与最近堆叠的边界匹配,则返回 并根据匹配是否为结束标记将 self.last 设置为 1 或 0。 如果该线与任何其他堆叠边界匹配,则引发错误。 在底层流对象上遇到文件结尾时,除非所有边界都已弹出,否则该方法会引发 Error
MultiFile.readlines(str)
返回此部分中剩余的所有行作为字符串列表。
MultiFile.read()
阅读所有行,直到下一部分。 将它们作为单个(多行)字符串返回。 请注意,这不需要大小参数!
MultiFile.seek(pos[, whence])
寻找。 搜索索引相对于当前部分的开始。 poswhence 参数被解释为文件搜索。
MultiFile.tell()
返回相对于当前节开头的文件位置。
MultiFile.next()
跳到下一部分(即,读取行,直到使用了部分分隔符或结束标记)。 如果有这样的部分,则返回 true,如果看到结束标记,则返回 false。 重新启用最近推送的边界。
MultiFile.is_data(str)

如果 str 是数据,则返回 true,如果它可能是节边界,则返回 false。 正如所写,它在行首(所有 MIME 边界都有)测试除 '--' 之外的前缀,但它被声明为可以在派生类中被覆盖。

请注意,此测试旨在作为真实边界测试的快速防护; 如果它总是返回 false,它只会减慢处理速度,而不会导致它失败。

MultiFile.push(str)

推一个边界字符串。 当发现此边界的装饰版本作为输入行时,它将被解释为节分隔符或结束标记(取决于装饰,请参阅 RFC 2045)。 所有后续读取将返回空字符串以指示文件结束,直到调用 pop() 删除边界 a 或 next() 调用重新启用它。

可以推多个边界。 遇到最近推送的边界会返回EOF; 遇到任何其他边界都会引发错误。

MultiFile.pop()
弹出一个部分边界。 此边界将不再被解释为 EOF。
MultiFile.section_divider(str)
将边界变成分节线。 默认情况下,此方法在 '--'(MIME 节边界具有)的前面,但它被声明为可以在派生类中被覆盖。 此方法不需要附加 LF 或 CR-LF,因为与结果的比较会忽略尾随空格。
MultiFile.end_marker(str)
将边界字符串转换为结束标记线。 默认情况下,此方法在 '--' 前面加上 '--'(如 MIME 多部分消息结束标记),但它被声明为可以在派生类中覆盖。 此方法不需要附加 LF 或 CR-LF,因为与结果的比较会忽略尾随空格。

最后, MultiFile 实例有两个公共实例变量:

MultiFile.level
当前零件的嵌套深度。
MultiFile.last
如果最后一个文件结束是消息结束标记,则为真。


18.10.2. 多文件例子

import mimetools
import multifile
import StringIO

def extract_mime_part_matching(stream, mimetype):
    """Return the first element in a multipart MIME message on stream
    matching mimetype."""

    msg = mimetools.Message(stream)
    msgtype = msg.gettype()
    params = msg.getplist()

    data = StringIO.StringIO()
    if msgtype[:10] == "multipart/":

        file = multifile.MultiFile(stream)
        file.push(msg.getparam("boundary"))
        while file.next():
            submsg = mimetools.Message(file)
            try:
                data = StringIO.StringIO()
                mimetools.decode(file, data, submsg.getencoding())
            except ValueError:
                continue
            if submsg.gettype() == mimetype:
                break
        file.pop()
    return data.getvalue()