Pythonasyncio异步编程常见问题小结

今天继续给大家介绍Python相关知识,本文主要内容是Python asyncio异步编程常见问题。

 

一、asyncio编程简单示例

首先,我们来看一段简单的Python asyncio异步编程代码,相关代码如下所示:

import asyncio

async def fun():
  print(1)
  await asyncio.sleep(2)
  print(2)
  return 3

async def main():
  task_list=[
      asyncio.create_task(fun()),
      asyncio.create_task(fun())
  ]
	done,pending=await asyncio.wait(task_list)
  print(done)
asyncio.run(main())

在上述代码中,我们使用了Task列表,将两个fun()协程函数生成的Task对象添加到task列表中,最终实现了这两个函数异步执行。上述代码执行结果如下所示:

 

二、asyncio编程常见问题

下面,我们想要简单的修改一下上述代码,我们把main()函数删除,尝试直接生成协程对象列表,结果如下所示:

import asyncio

async def fun():
  print(1)
  await asyncio.sleep(2)
  print(2)
  return 3

task_list=[
  asyncio.create_task(fun()),
  asyncio.create_task(fun())
]

done,pending=asyncio.run(asyncio.wait(task_list))
print(done)

上述代码执行结果如下所示:

 

三、报错原因及解决方案

从上图中可以看出,上述代码执行报错,错误提示为:RuntimeError:no running event loop。
其实,之所以出现上述报错,直接原因在于当前没有事件循环。当我们使用asyncio模块来实现异步编程时,asyncio模块的优点在于省略了我们创建事件循环的过程,但是这并不意味着asyncio异步编程不需要事件循环。事实上,在第一段代码中,代码:

asyncio.run(main())

在实际上创建了这个事件循环,但是asyncio模块屏蔽了这一细节。而正是因为已经存在了事件循环,因此我们才可以执行命令:

done,pending=await asyncio.wait(task_list)

但是在上述代码中,我们没有创建事件循环,而是直接将该代码放到主程序中执行,因此上述代码会出现报错。
针对上述代码,我们可以简单修改为以下内容:

import asyncio

async def fun():
  print(1)
  await asyncio.sleep(2)
  print(2)
  return 3

task_list=[
  fun(),
  fun()
]

done,pending=asyncio.run(asyncio.wait(task_list))
print(done)

在上述代码中,我们的Task列表中存放的是协程对象,而不是Task对象,这样,我们在执行asyncio.wait时会自动创建一个事件循环,并且把协程对象加入到事件循环中。因此上述代码也就不会报错了。执行结果如下所示:

关于Python asyncio异步编程常见问题小结的文章就介绍至此,更多相关Python asyncio异步内容请搜索编程宝库以前的文章,希望以后支持编程宝库

 准备工作没有加壳的python编译并打包的exe文件python反打包代码(不知道这样叫是否合理):python-exe-un ...