1

文字列または開いているファイル オブジェクトのいずれかを受け入れたい (再帰的) 関数があります。引数が文字列の場合、関数はファイルを開き、そのファイル オブジェクトを使用します。関数から戻ったときに、この開いているファイル オブジェクトを明示的に閉じるのが最善のようですが、それは文字列が渡された場合のみです。 )。これが私が現在使用しているものです:

def read_file(f, param):
    do_close = isinstance(f,basestring)
    f = open(f, 'rb') if do_close else f
    try:
        info = f.read(4)
        #check info here
        if info == Info_I_Want(param):
           return f.read(get_data(info))
        else:
           f.seek(goto_new_position(info))
           return read_file(f,param)
    except IKnowThisError:
           return None
    finally:
        if do_close:
           f.close()

IKnowThisError必要な情報が見つからない場合は、ある時点で引き上げられると想定できます。

これは非常に下品な気がします。より良い方法はありますか?

4

3 に答える 3

3

Why not wrapping your recursive function with a wrapper to avoid overhead ?

def read_file(f, param):
    if isinstance(f, basestring):
        with open(f, 'rb') as real_f:
            return read_file2(real_f, param)
    else:
        return read_file2(real_f, param)

def read_file2(f, param):
    # Now f should be a file object
    ...
于 2012-08-02T13:28:48.093 に答える
2

関数を再帰的に呼び出すのはどうですか?

def read_file(f, param):
    if isinstance(f, basestring):
        with open(f, 'rb') as real_f:
            return read_file(real_f, param)
    else:
        # normal path
于 2012-08-02T13:25:56.887 に答える
1

次期 Python 3.3 では、この種の問題に対するより一般的な解決策、つまりcontextlib.ExitStack. これにより、現在の with-block にコンテキスト マネージャーを条件付きで追加できます。

def read_file(f, param):
    with ExitStack() as stack:
        if isinstance(f, basestring):
            f = stack.enter_context(open(f, 'rb'))
        # Your code here
于 2012-08-02T13:41:47.530 に答える