我正在编写使用协同程序的代码,我想在关机时采取可靠的行为。
说我有一个协程和一个上下文管理器:
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
答案 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)