在coroutine close()

时间:2017-10-10 23:22:30

标签: python python-3.x coroutine

我正在编写使用协同程序的代码,我想在关机时采取可靠的行为。

说我有一个协程和一个上下文管理器:

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()上执行我自己的代码。特别是协程中的上下文管理器从不打印“退出coro”

协同程序中的上下文管理器有什么意义?我是否必须手动设置一种方式来表示流的结束?那么close()有什么意义呢?

请参阅此示例:https://repl.it/M0XI/0

1 个答案:

答案 0 :(得分:1)

您的上下文管理器有错误。纠正它,当协程关闭时它会自动执行清理。

关闭协程的工作方式是在协程挂起的位置引发GeneratorExit。如果with中的代码引发异常,则@contextlib.contextmanager会在yield处引发该异常。您的上下文管理器不会处理该问题,因此异常会阻止清理运行。

你需要将yield包装在try-finally中并在finally中进行清理,如果你希望清理在异常时运行:

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