Skip to main content
 首页 » 编程设计

python之尝试将文件作为存档打开,否则作为普通文件读取

2025年05月04日9fff_TT

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

我怎样才能最有效地使用 try-except block 来尝试以适当的格式打开每个文件?我宁愿不检查文件的扩展名,因为这并不总是可靠的(而且不是很 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 block 策略,看起来你会很快开始嵌套在 block 中,即使只是几种格式,例如:

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

请您参考如下方法:

如果您担心的只是重复的循环,您可以将 f 移出 try-catch block 的范围,然后在一切都说完之后放置一个循环副本,完成:

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 header (字符 BZ 作为前两个字节),并使用它来决定是否继续以明文形式读取它,或将数据传递到 bz2.BZ2Decompressor 实例中。