我试图了解如何使用 Spyder IDE 在 python 中运行异步调用。
我写了以下代码:
import asyncio
from concurrent.futures import ThreadPoolExecutor
async def factorial(number):
f = 1
for i in range(2, number + 1):
await asyncio.sleep(1)
f *= i
print(f"Task {number}: factorial({number}) = {f}")
return f
async def main():
# Schedule three calls *concurrently*:
executor = ThreadPoolExecutor(max_workers=10)
loop = asyncio.get_event_loop()
L = [await loop.run_in_executor(executor, factorial, i) for i in range(2,5)]
L = await asyncio.gather(*L)
print(L)
return(L)
if __name__ == '__main__':
a = asyncio.create_task(main())
if a.done():
res = a.result()
print("RESULT:",res)
print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
我希望从 asyncio,create_task 获得结果,但从 Spyder 的控制台得到以下结果:
在[1]中:
啊啊啊啊啊啊啊啊啊啊啊啊啊
任务 2:阶乘(2) = 2
任务 3:阶乘(3) = 6
任务 4:阶乘(4) = 24
[2,6,24]
看起来 print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") 在我从 asyncio.create_task() 获得结果之前正在运行,实际上我没有看到屏幕 print("RESULT:",res) 上打印的结果。
我缺少什么?
非常感谢任何帮助。
这个问题似乎是间谍程序特有的,我假设您遇到了由于已经存在的事件循环而无法使用
asyncio.run()
的问题。通常你会这样做:
res = asyncio.run(main())
print("RESULT:", res)
但是由于这显然不适用于spyder,因此我们需要其他选择。
目前
a = asyncio.create_task(main())
发生的情况是,您实际上是在创建一个您不等待的任务。您最好的选择是将所有代码从 asyncio.create_task(main())
移至 main()
,这就是该函数的要点。您基本上已经用 print(L)
打印了结果,那么您还需要其他打印吗?
就像我说的,通常你会
await
使用create_task
创建的任何东西。现在您检查一次结果然后放弃,这就是最终打印执行得太早的原因。由于如果没有在 async
函数中,await 将无法工作,因此您需要其他东西,也许是 while 循环:
if __name__ == '__main__':
a = asyncio.create_task(main())
while not a.done():
asyncio.sleep(1)
res = a.result()
print("RESULT:",res)