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

本当に重複したループだけが気になる場合fは、try-catch ブロックの範囲外に移動して、すべての処理が完了した後にループの 1 つのコピーを配置することができます。

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()

ファイルを 1 回だけ開き、BZ2 ヘッダー (BZ最初の 2 バイトの文字) を確認し、それを使用してプレーンテキストとして読み取りを続行するか、データをbz2.BZ2Decompressorインスタンスに渡すかを決定します。

于 2013-03-21T03:30:53.007 に答える