运行 协程 close() 代码

Run code on coroutine 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() 上执行我自己的代码。特别是协程中的上下文管理器从不打印 "Exit coro"

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

看这个例子:https://repl.it/M0XI/0

您的上下文管理器有错误。更正一下,协程关闭时会自动进行清理。

关闭协程是通过在协程被挂起的地方引发 GeneratorExit 来实现的。如果 with 中的代码引发异常,则 @contextlib.contextmanager 会在 yield 处引发该异常。您的上下文管理器不处理该问题,因此异常会阻止 运行ning.

进行清理

您需要将 yield 包装在 try-finally 中,并在 finally 中进行清理,如果您希望清理到 运行,即使出现异常也是如此:

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