给出以下最小示例:
@asynccontextmanager
async def async_context():
try:
yield
finally:
await asyncio.sleep(1)
print('finalize context')
async def async_gen():
try:
yield
finally:
await asyncio.sleep(2)
# will never be called if timeout is larger than in async_context
print('finalize gen')
async def main():
async with async_context():
async for _ in async_gen():
break
if __name__ == "__main__":
asyncio.run(main())
我正在break
遍历异步生成器,并且希望在异步上下文管理器finally
块运行之前完成finally块。在此示例中,"finalize gen"
将永远不会打印,因为程序会在此之前退出。
请注意,我有意2
在generatorsfinally
块中选择的超时,因此上下文管理器finally
有机会在之前运行。如果我1
为两个超时都选择了,则将同时打印两条消息。
这是比赛条件吗?我希望所有程序finally
块都能在程序完成之前完成。
如何防止上下文finally
生成器finally
块在generators块完成之前运行?
对于上下文:
我使用编剧来控制Chrome浏览器。外部上下文管理器提供了一个页面,该页面将在finally
块中关闭。
我正在使用python 3.9.0
。
请尝试以下示例:https : //repl.it/@trixn86/AsyncGeneratorRaceCondition
异步上下文管理器对异步生成器一无所知。实际上main
,您对异步生成器一无所知break
。您没有办法等待生成器的完成。
如果要等待生成器关闭,则需要显式处理关闭操作:
async def main():
async with async_context():
gen = async_gen()
try:
async for _ in gen:
break
finally:
await gen.aclose()
在Python 3.10中,您可以使用contextlib.aclosing
而不是try / finally:
async def main():
async with async_context():
gen = async_gen()
async with contextlib.aclosing(gen):
async for _ in gen:
break
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句