![](/img/trans.png)
[英]Using nested asyncio.gather() inside another asyncio.gather()
[英]asyncio.gather with generator expression
為什么 asyncio.gather 不能與生成器表達式一起使用?
import asyncio
async def func():
await asyncio.sleep(2)
# Works
async def call3():
x = (func() for x in range(3))
await asyncio.gather(*x)
# Doesn't work
async def call3():
await asyncio.gather(func() for x in range(3))
# Works
async def call3():
await asyncio.gather(*[func() for x in range(3)])
asyncio.run(call3())
第二種變體給出:
[...]
File "test.py", line 13, in <genexpr>
await asyncio.gather(func() for x in range(3))
RuntimeError: Task got bad yield: <coroutine object func at 0x10421dc20>
這是預期的行為嗎?
await asyncio.gather(func() for x in range(3))
這不起作用,因為這將生成器 object作為參數傳遞給gather
。 gather
不期望一個可迭代的,它期望協程作為單獨的 arguments。 這意味着您需要打開生成器的包裝。
打開生成器的包裝:
await asyncio.gather(*(func() for i in range(10))) # star expands generator
我們必須擴展它,因為asyncio.gather
需要一個 arguments 列表(即asyncio.gather(coroutine0, coroutine1, coroutine2, coroutine3)
),而不是一個可迭代的
Python 使用*
/ **
用於“解包”和“打包”,具體取決於它是否用於變量賦值。
def foo(*args,**kwargs):...
在這種情況下,所有非關鍵字 args 都被放入一個元組args
中,所有 kwargs 都被打包到一個新字典中。 傳入的單個變量仍被打包到元組( *
)或字典( **
)中。
這是一種混合
first,*i_take_the_rest,last = range(10)
>>> first=0,i_take_the_rest=[1,2,3,4,5,6,7,8],last=9
*a,b = range(1)
>>> a=[],b=0
但在這里它解包:
combined_iterables = [*range(10),*range(3)]
merged_dict = {**first_dict,**second_dict}
所以基本上,如果它位於等號的左側,或者如果它用於像*foo
這樣的函數/方法定義中,它會將內容打包到列表或元組中(分別)。 然而,在理解中,它具有解包行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.