提问人:Nattōsai Mitō 提问时间:10/26/2020 最后编辑:Nattōsai Mitō 更新时间:10/29/2020 访问量:769
当没有引用 'await' 时,其 finally 块中没有 'await' 的异步生成器是否会立即关闭?
Will async-generators that don't have 'await' in its finally-block be immediately closed when there is no reference to it?
问:
根据这篇博客,当没有参考时,普通发电机将立即关闭。(CPython 独家)。我的问题是“这是否适用于在其最终块中没有”await“的异步生成器?
赋予动机
我是异步库的专家,希望异步生成器像普通生成器一样工作。否则,用户必须编写如下代码
agen = async_generator_function()
async with async_closing(agen):
async for v in agen:
if some_condition:
break
do_something()
取而代之的是这个
async for v in async_generator_function():
if some_condition:
break
do_something()
这很烦人。幸运的是,它的单元测试总是像我预期的那样工作,所以我想知道它是否得到保证。
调查
以下代码
import asyncio
async def agen_func():
try:
for i in range(10):
yield i
finally:
print('finalized')
async def main():
async for i in agen_func():
print(i)
if i > 2:
break
print('end of main()')
asyncio.run(main())
印刷
0
1
2
3
end of main()
finalized
和下面的代码
import trio
async def agen_func():
try:
for i in range(10):
yield i
finally:
print('finalized')
async def main():
async for i in agen_func():
print(i)
if i > 2:
break
print('end of main()')
trio.run(main)
打印相同的,看起来两者都像,并对我的问题说“不”,因为如果异步生成器像我预期的那样立即关闭,它们就会在之前打印.实际上,如果您使用这两个异步库,我问题的答案可能是“否”。asyncio
trio
finalized
end of main()
但这里有一件有趣的事情。如果你不使用它们,异步生成器会按我的预期工作。
async def agen_func():
try:
for i in range(10):
yield i
finally:
print('finalized')
async def main():
async for i in agen_func():
print(i)
if i > 2:
break
print('end of main()')
try:
main().send(None)
except StopIteration:
pass
0
1
2
3
finalized
end of main()
这就是我目前正在开发的异步库的工作方式。
set_asyncgen_hooks
根据 PEP525 的说法,做了一些叫做 . 也是。我相信这就是异步生成器在它们下无法像我预期的那样工作的原因。这是可以理解的,因为它对于其 finally-block 包含 .asyncio
sys.set_asyncgen_hooks()
trio
await
更精确的问题
所以我的问题是:
如果你使用的是 CPython,而你使用的异步库没有做上面的 hacky 事情,那么当没有引用它时,没有在其 finally-block 中的异步生成器将立即关闭?await
环境
- CPython 3.8.1 版本
- 三重奏 0.17.0
答: 暂无答案
评论