首页 > 解决方案 > 在 Python 中创建异步函数

问题描述

我有 4 个用 python 编写的函数。我想让前 3 个函数异步。所以它应该是这样的:

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>>)

有什么帮助吗?

标签: pythonasynchronous

解决方案


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)

推荐阅读