2

ジェネレーターがリソースを管理することは可能です。たとえばyield、コンテキスト マネージャー内から 'ing することによってです。リソースはclose()、ジェネレーターのメソッドが呼び出される (または例外が発生する) とすぐに解放されます。

最後に呼び出すのを忘れがちなので、close()そのためにもコンテキストマネージャーを使用することは明らかだと思います(また、潜在的な例外を処理するためにも)。私はそれを使用できることを知っていますが、ステートメントcontextlib.closingでジェネレーターを直接使用する方がはるかに優れていると思いませんか?with

ジェネレーターがコンテキストマネージャーであってはならない理由はありますか?

4

2 に答える 2

1

Wheaties が言ったように、クラスには「1 つのことだけを適切に」実行させたいと考えています。特にコンテキスト マネージャーでは、コンテキストを管理しています。ここでの文脈は何ですか?ほとんどの場合、リソースを開いています。少し前に、コンテキスト マネージャーでキューを使用することについて質問しましたが、基本的に、キューはコンテキストとして意味がないという回答でした。しかし、「タスク内」は私がいる実際のコンテキストであり、そのためのコンテキスト マネージャーを作成することは理にかなっています。

さらに、反復withステートメントはありません。たとえば、ファイルを開いて、次のような 1 つのステートメントで反復処理することはできません。

for line in file with open(filename) as file:
    ...

次の 2 行で実行する必要があります。

with open(filename) as file:
    for line in file:
        ...

管理されているコンテキストは「ファイルを繰り返し処理している」ではなく、「ファイルを開いている」ため、これは良いことです。繰り返しますが、コンテキストは何ですか?あなたは本当に何をしているのですか?ほとんどの場合、マネージド コンテキストは実際にはリソースの反復ではありません。ただし、特定の問題を見ると、ジェネレーターがコンテキストを管理している状況が実際にあることに気付くかもしれません。コンテキストが実際に何であるかを理解することで、それを適切に管理する方法についていくつかのアイデアが得られることを願っています。

于 2014-06-03T19:20:26.023 に答える