tzi*_*nge 3 python python-asyncio
我遇到了一种情况,我想打破异步 for 循环。我设法将问题减少到下面的应用程序。我希望在退出 main 中的循环时进入上下文管理器的“最后”部分。换句话说,预期的结果是
尝试
第456章
最后
完毕
但我得到的是
尝试
第456章
完毕
最后
然后当应用程序关闭时出现异常。
这是代码
import asyncio
from contextlib import asynccontextmanager
@asynccontextmanager
async def receiving():
try:
print('try')
yield 123
finally:
print('finally')
async def request_all():
async with receiving():
yield 456
async def main():
async for r in request_all():
print(r)
break
print('done')
asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)
我发现这个错误报告看起来很相似,但据我所知,它在 3.8 之前就已得到解决。我在 3.8.2 和 3.9.6 上测试了我的问题
我可以看出这种行为是多么令人困惑,但我不认为这是一个错误。如果您使用 绕过异步迭代器的耗尽break,则永远不会离开async within request_all,因此finally-block 在事件循环完成之前不会被执行。这样做的好处是您可以稍后耗尽发电机的电量。
如果您确定不再需要生成器,您可以关闭 async_generator 而不是breaking 来获得预期的行为:
import asyncio
from contextlib import asynccontextmanager
@asynccontextmanager
async def receiving():
try:
print('try')
yield 123
finally:
print('finally')
async def request_all():
async with receiving():
yield 456
async def main():
gen = request_all()
async for r in gen:
print(r)
await gen.aclose() #instead of break
print('done')
asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3307 次 |
| 最近记录: |