python - 从 Python 异步中断

标签 python python-asyncio

我有一种情况想从异步 for 循环中中断。我设法将问题减少到下面的应用程序。我希望在从 main 中的循环中断时进入上下文管理器的“最后”部分。也就是说,预期的结果是

try

456

finally

done

但我得到的是

try

456

done

finally

然后在应用程序关闭时出现异常。

这是代码

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())

我发现 this 错误报告看起来很相似,但据我所知,它已在 3.8 之前得到解决。我在 3.8.2 和 3.9.6 上测试了我的问题

最佳答案

我可以看出这种行为是多么令人困惑,但我不认为这是一个错误。如果你用 break 绕过异步迭代器的耗尽,你永远不会在 request_all 中留下 async with,所以 finally code>-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())

关于python - 从 Python 异步中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69836366/

相关文章:

Python asyncio,可以等待/产生整个 myFunction()

python - 断言错误 : yield from wasn't used with future

python-3.x - 线程和异步: Task was destroyed but it is pending

Python加速大型嵌套数组处理

python - 基于另一个数组中的信息对 NumPy 数组进行操作

java - 用 Linux 读取 USB 读卡器? OMNIKEY CardMan 3121 USB

python - __repr__ 方法的目的?

python - 当我尝试使用 asyncpg 的 executemany 方法时,出现神秘的 KeyError

python - 同时处理 2 个 websocket 连接的最佳方法

python - 如何为 Google App Engine 实现简单 session ?