在Python中制作异步函数

时间:2020-10-22 09:35:17

标签: python asynchronous

我有4个用python写的函数。我想使前三个功能异步。 所以它应该像这样:

x = 3.13
def one(x):
   return x**x

def two(x):
   return x*x*12-314

def three(x):
   return x+x+352+x**x


def final(x):

   one = one(x)
   two = two(x)
   three = three(x)

   return one, two, three

这就是我所做的:

async def one(x):
   return x**x

async def two(x):
   return x*x*12-314

async def three(x):
   return x+x+352+x**x


def final(x):

   loop = asyncio.get_event_loop()

   one = loop.create_task(one(x))
   two = loop.create_task(two(x))
   three = loop.create_task(three(x))


   #loop.run_until_complete('what should be here')
   #loop.close()

   return one, two, three

但是我得到这个错误(如果上面的行没有注释):

RecursionError: maximum recursion depth exceeded

我不知道出了什么问题(这是我的新手),我也尝试添加此内容:

await asyncio.wait([one,two,three])

但是说实话,我不知道在哪里以及为什么要添加它。 否则,我的代码将起作用,但不会给我结果,它将显示以下内容:

(<Task pending name='Task-1' coro=<one() running at /Users/.../Desktop/....py:63>>, <Task pending name='Task-2' coro=<two() running at /Users/.../Desktop/...py:10>>, <Task pending name='Task-3' coro=<three() running at /Users/.../Desktop/...py:91>>)

有帮助吗?

1 个答案:

答案 0 :(得分:2)

async语法及其库的主要目的是隐藏事件循环的详细信息。首选直接使用高级API:

def final(x):
   loop = asyncio.get_event_loop()
   return loop.run_until_complete(  # run_until_complete fetches the task results
       asyncio.gather(one(x), two(x), three(x))  # gather runs multiple tasks
   )

print(final(x))  # [35.5675357348548, -196.43720000000002, 393.8275357348548]

如果您要显式控制并发性,即当函数作为任务启动时,在另一个async函数中执行此操作会更简单。在您的示例中,将final设为async函数可以直接访问await和环境循环,从而简化了事情:

async def final(x):  # async def – we can use await inside
   # create task in whatever loop this function runs in
   task_one = asyncio.create_task(one(x))
   task_two = asyncio.create_task(two(x))
   task_three = asyncio.create_task(three(x))
   # wait for completion and fetch result of each task
   return await task_one, await task_two, await task_three

print(asyncio.run(final(x)))  # (35.5675357348548, -196.43720000000002, 393.8275357348548)