multifile
multifile — Support for files containing distinct parts
自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
旨在支持可能具有多个嵌套消息部分的消息的解析,每个消息部分都有自己的部分分隔符和结束标记行模式。
1.多文件对象
一个MultiFile
实例有以下方法:
MultiFile.readline(str)
阅读一行。如果该行是数据(不是分节符或结束标记或真正的EOF),则将其返回。如果该行匹配最近堆叠的边界,则返回''
并self.last
根据匹配是否是结束标记设置为1或0。如果该线匹配任何其他堆积的边界,则引发错误。在遇到底层流对象的文件结尾时,Error
除非所有边界都被弹出,否则该方法会引发。
MultiFile.readlines(str)
将这部分剩余的所有行作为字符串列表返回。
MultiFile.read()
阅读所有行,直到下一部分。将它们作为单个(多行)字符串返回。请注意,这不需要大小参数!
MultiFile.seek(pos[, whence])
寻求。寻找索引是相对于当前部分的开始。该POS
和那里
参数被解释为文件查找。
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
如果最后一个文件结束符是消息结束标记,则为真。
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()