2

我正在尝试处理文件列表,其中每个文件可能是常规文本文件或 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:
            ...
4

1 回答 1

1

如果它真的只是让你担心的重复循环,你可以移出ftry-catch 块的范围,然后在一切都说完之后放一个循环的副本:

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实例中。

于 2013-03-21T03:30:53.007 回答