【问题标题】:Try opening a file as an archive, otherwise read as a regular file尝试将文件作为存档打开,否则作为常规文件读取
【发布时间】:2013-03-10 10:05:32
【问题描述】:

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

【问题讨论】:

    标签: python file archive bzip2


    【解决方案1】:

    如果确实只是重复循环让您担心,您可以将 f 移出 try-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 实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-19
      • 2021-12-04
      • 1970-01-01
      • 1970-01-01
      • 2018-09-22
      • 1970-01-01
      相关资源
      最近更新 更多