尝试将文件作为存档打开,否则将其作为常规文件读取

时间:2013-03-21 02:19:43

标签: python file archive bzip2

我正在尝试处理文件列表,其中每个文件可能是常规文本文件或bz2存档。

如何最有效地使用try-except块来尝试以适当的格式打开每个文件?我宁愿不检查文件的扩展名,因为这不能总是依赖(并且不是EAFP)。

目前我在做:

def data_generator(*corpora):
    def parse_lines(fobj):
        for line in fobj:
            # Do lots of processing.
            # ...
            # Many lines here omitted.
            yield ('lots', 'of', 'data')

    for corpus in corpora:
        try:
            with bz2.BZ2File(corpus, mode='r') as f:
                for data in parse_lines(f):
                    yield data
        except IOError:
            with codecs.open(corpus, encoding='utf-8') as f:
                for data in parse_lines(f):
                    yield data

我认为重复的for data in parse_lines(f): ...代码看起来多余,但我想不出办法摆脱它。有没有办法减少之前的,还是有另一种方法来尝试“智能打开”文件?

编辑:可选后续

扩大检查格式数量的适当方法是什么?例如,程序7zip允许您右键单击任何文件并尝试将其作为存档(任何7zip支持)打开。使用当前的try-except块策略,看起来即使在几种格式之后你也会很快嵌套在块中,例如:

try:
    f = ...
except IOError:
    try:
        f = ...
    except IOError:
        try:
            ...

1 个答案:

答案 0 :(得分:1)

如果它真的只是你所关心的重复循环,你可以将f移出try-catch块的范围,然后在完成所有内容之后放置一个循环的副本:< / p>

try:
    f = bz2.BZ2File(corpus, mode='r')
except IOError:
    f = codecs.open(corpus, encoding='utf-8')
for data in parse_lines(f):
    yield data
f.close()

虽然我只考虑打开文件一次,检查BZ2标头(字符BZ作为前两个字节),并用它来决定是继续以明文形式读取,还是通过将数据转换为bz2.BZ2Decompressor实例。