2017-10-10 6 views
0

私はコルーチンを大量に使用するコードを書いています。コルーチンでコードを実行close()

は、私はコルーチンとコンテキストマネージャを持って言う:

from contextlib import contextmanager 

@contextmanager 
def print_context_manager(text): 
    print("Enter", text) 
    yield 
    print("Exit", text) 

def coro(): 
    with print_context_manager("coro"): 
     while True: 
      print("Loop", (yield)) 

私はこのようにそれを使用することができます。

c = coro() 
next(c) 
c.send("Hello ") 
c.send("World!") 
c.close() 

残念ながら、私の知る限り、実行する方法はありません私のコードはc.close()です。特に、コルーチンのコンテキストマネージャは「出口コロ」を印刷しません

コルーチンのコンテキストマネージャのポイントは何ですか?ストリームの終わりを伝える方法を手動で考えなければなりませんか?次にclose()のポイントは何ですか?

は、この例を参照してください:https://repl.it/M0XI/0

+1

「特にwrite_to_fileのコルーチンでファイルのコンテキストマネージャを決してファイルを閉じます。 "あなたはこれについて確信を持っていますか?コルーチンを閉じても最終的にブロックが実行されず、コンテキストマネージャから抜け出せば驚くでしょう。 –

+0

ジェネレータコルーチンまたは新しい類似した別の非同期コルーチンのどちらであっても、コルーチンを閉じることで 'finally'ブロックと' __exit__'メソッドが実行されます。それを行うために独自の処理を書く必要はありません。 – user2357112

+0

問題を示す例を以下に示します:https://repl.it/M0XI/0。私が間違っていることを見ることができたら、私に知らせてください。 –

答えて

1

あなたのコンテキストマネージャは、バグがあります。これを修正すると、コルーチンが閉じられたときにクリーンアップが自動的に実行されます。

コルーチンを閉じると、コルーチンが中断された時点でGeneratorExitが発生します。 withのコードで例外が発生した場合、@contextlib.contextmanageryieldの時点でその例外を発生させます。コンテキストマネージャはそれを処理しないので、例外によってクリーンアップが実行されなくなります。

あなたがしよう、最終的にyieldをラップして、クリーンアップは例外にしても実行したい場合finallyでクリーンアップを行う必要がありません:

@contextmanager 
def print_context_manager(text): 
    print("Enter", text) 
    try: 
     yield 
    finally: 
     print("Exit", text) 
関連する問題