2017-10-10 4 views
0

나는 coroutines를 많이 사용하는 코드를 작성하고 있으며, 종료시 신뢰할 수있는 동작을 원합니다. 지금까지 내가 말할 수있는, 실행할 수있는 방법이 없습니다, 불행히도코 루틴에서 코드 실행 닫기()

c = coro() 
next(c) 
c.send("Hello ") 
c.send("World!") 
c.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.close()입니다. 특히 coroutine의 컨텍스트 관리자는 "Exit coro"를 출력하지 않습니다.

coroutines에서 컨텍스트 관리자의 핵심은 무엇입니까? 스트림의 끝을 알리는 방법을 수동으로 찾아야합니까? 그러면 close()의 포인트는 무엇입니까?

이 예를 참조하십시오 https://repl.it/M0XI/0

+1

"write_to_file의 코 루틴의 파일 컨텍스트 관리자 결코 파일을 닫습니다. " 이거 확실하니? 동시 루틴을 닫으면 블록이 실행되지 않고 컨텍스트 관리자가 종료됩니다. –

+0

생성자 - 코 루틴 또는 새로운 유사하지만 다른 비동기 코 루틴에 상관없이, 코 루틴을 닫으면'finally' 블록과'__exit__' 메소드가 실행됩니다. 이를 수행하기 위해 자체 처리 작업을 작성할 필요가 없습니다. – user2357112

+0

다음은 문제를 보여주는 예제입니다. https://repl.it/M0XI/0. 내가 뭘 잘못하고 있는지 알 수 있다면 알려주십시오. –

답변

1

귀하의 상황에 맞는 관리자가 버그가 있습니다. Coroutine이 닫히면이를 정정하고 자동으로 정리를 수행합니다.

코 루틴을 닫으면 코 루틴이 일시 중단 된 지점에서 GeneratorExit을 일으킴으로써 작동합니다. with의 코드가 예외를 발생시키는 경우 @contextlib.contextmanageryield 지점에서 예외를 발생시킵니다. 컨텍스트 관리자는이를 처리하지 않으므로 예외로 인해 정리가 실행되지 않습니다.

당신은 시도 - 마지막에 yield을 포장하고 정리도 예외에서 실행하려는 경우 finally에 정리를 할 필요가 :

특히
@contextmanager 
def print_context_manager(text): 
    print("Enter", text) 
    try: 
     yield 
    finally: 
     print("Exit", text) 
관련 문제