3

スクリプトがその結果を標準出力に出力するか、定義済みの結果ファイルに出力するかを、コマンド ラインで渡すオプションがあるスクリプトをプログラミングしています。このコードの概要を以下に示します。Python のコンテキスト マネージャーについて少し読んだことがありますが、この特定の状況でコンテキスト マネージャーを使用するかどうか、またどのように使用するかはよくわかりません。なのでアドバイス募集中です

  1. この問題でコンテキスト マネージャーを使用する意味があるかどうか
  2. それを実装する方法。

したがって、コンテキスト マネージャーを使用しないコードは次のようになります。

option_file = True # would come from OptionParser in real code

if option_file:
    out = open("resultsfile", "w")
else:
    out = sys.stdout

# do some computations
out.write("Results of script")
# more computations and calls to out.write

if option_file:
    out.close()
4

1 に答える 1

4

withコンテキスト マネージャーは、ステートメントで使用できるものです。以下の目的で明示的に設計されています。

  • いくつかのセットアップを実行し、
  • あなたにオブジェクトを与え、そして
  • (例外を発生させたとしても) ティアダウンを再度実行します。

たとえばopen、コンテキスト マネージャーとして使用できます。次のコードでは

with open(...) as f:
    # do stuff

stuffファイルは常に閉じられます。(まあ、通常。電源が切られたり、プロセスが強制終了されたりするようなばかげた場合を除いて。)

このような状況では、コンテキスト マネージャーを使用する必要があります。あなたのようには見えないので、コンテキストマネージャーの理由はわかりません。


コンテキスト マネージャーを使用するコードを記述する別の方法 (良くも悪くもありません) があります。一時的にリダイレクトしたいstdoutが、完了したら元に戻す必要がある場合は、上記の状況になります。次に例を示します。

@contextlib.contextmanager
def redirect_stdout(stream):
    import sys
    sys.stdout = stream
    yield
    sys.stdout = sys.__stdout__

その後、次のようなコードを書くことができます

with open(...) as f:
    with redirect_stdout(f):
        # do stuff

stdout への書き込みはすべてstuff代わりに行われfます。


編集:コンテキストマネージャーを条件付きで使用する方法がないことは正しいです:あなたが1つにいるか、そうでないかのどちらかです。何もしないかもしれない独自のものをいつでも書くことができます:

@contextlib.contextmanager
def maybe_open(path, do_nothing=True):
    if do_nothing:
        f = None
        yield sys.stdout
    else:
        f = open(path)
        yield f

    if f:
        f.close()

これはほぼ間違いなくやり過ぎです。

于 2011-12-13T20:30:43.130 に答える