asyncio.gather 抛出 RuntimeError: Task got bad yield

Mes*_*ssa 2 python python-asyncio

我想使用asyncio.gather() “并行”运行一些任务:

import asyncio

async def foo():
    return 42

async def main():
    results = await asyncio.gather(foo() for i in range(10))
    print(results)

asyncio.run(main())
Run Code Online (Sandbox Code Playgroud)

但它失败了RuntimeError: Task got bad yield

/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/events.py:88: RuntimeWarning: coroutine 'foo' was never awaited
  self._context.run(self._callback, *self._args)
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 583, in run_until_complete
    return future.result()
  File "<stdin>", line 2, in main
  File "<stdin>", line 2, in <genexpr>
RuntimeError: Task got bad yield: <coroutine object foo at 0x10555bd40>
Run Code Online (Sandbox Code Playgroud)

Mes*_*ssa 7

该函数asyncio.gather()接受每个任务作为单独的参数。像这样:

await asyncio.gather(task1, task2, task3)
Run Code Online (Sandbox Code Playgroud)

所以解决办法是更换

await asyncio.gather(task1, task2, task3)
Run Code Online (Sandbox Code Playgroud)

    results = await asyncio.gather(foo() for i in range(10))
Run Code Online (Sandbox Code Playgroud)

  • @ThomasSchillaci 这是允许的。如果未来的读者偶然发现这个问题,那么他们就会看到答案。 (5认同)
  • `await asyncio.gather(*(foo() for i in range(10)))` 是另一种选择,其优点是避免创建(立即丢弃的)临时列表。 (5认同)
  • 是的。https://stackoverflow.blog/2011/07/01/its-ok-to-ask-and-answer-your-own-questions/ (4认同)