Python协程还不理解?请收下这份超详细的异步编程教程( 三 )


Python协程还不理解?请收下这份超详细的异步编程教程

文章插图
 
运行结果:
Python协程还不理解?请收下这份超详细的异步编程教程

文章插图
 
这里我们定义了 loop 对象之后,接着调用了它的 create_task 方法将 coroutine 对象转化为了 task 对象,随后我们打印输出一下,发现它是 pending 状态 。接着我们将 task 对象添加到事件循环中得到执行,随后我们再打印输出一下 task 对象,发现它的状态就变成了 finished,同时还可以看到其 result 变成了 1,也就是我们定义的 execute 方法的返回结果 。
另外定义 task 对象还有一种方式,就是直接通过 asyncio 的 ensure_future 方法,返回结果也是 task 对象,这样的话我们就可以不借助于 loop 来定义,即使我们还没有声明 loop 也可以提前定义好 task 对象,写法如下:
Python协程还不理解?请收下这份超详细的异步编程教程

文章插图
 
运行结果:
Python协程还不理解?请收下这份超详细的异步编程教程

文章插图
 
发现其运行效果都是一样的 。
2.2 创建 task 总结
  1. 以下代码都是异步函数
  2. loop = asyncio.get_event_loop()task = loop.create_task(coroutine) # 需要提前声明 loop
  3. task = asyncio.create_task(net())
  4. task = asyncio.ensure_future(coroutine) # 不需要提前声明
2.3 绑定回调另外我们也可以为某个 task 绑定一个回调方法,比如我们来看下面的例子:
Python协程还不理解?请收下这份超详细的异步编程教程

文章插图
 
在这里我们定义了一个 request 方法,请求了百度,获取其状态码,但是这个方法里面我们没有任何 print 语句 。随后我们定义了一个 callback 方法,这个方法接收一个参数,是 task 对象,然后调用 print 方法打印了 task 对象的结果 。这样我们就定义好了一个 coroutine 对象和一个回调方法,我们现在希望的效果是,当 coroutine 对象执行完毕之后,就去执行声明的 callback 方法 。
那么它们二者怎样关联起来呢?
很简单,只需要调用 add_done_callback方法即可,我们将 callback 方法传递给了封装好的 task 对象,这样当 task 执行完毕之后就可以调用 callback 方法了,同时 task 对象还会作为参数传递给 callback 方法,调用 task 对象的 result 方法就可以获取返回结果了 。
运行结果:
Python协程还不理解?请收下这份超详细的异步编程教程

文章插图
 
实际上不用回调方法,直接在 task 运行完毕之后也可以直接调用 result 方法获取结果,如下所示:
Python协程还不理解?请收下这份超详细的异步编程教程

文章插图
 
运行结果是一样的:
Python协程还不理解?请收下这份超详细的异步编程教程

文章插图
 
2.4 多任务协程上面的例子我们只执行了一次请求,如果我们想执行多次请求应该怎么办呢?我们可以定义一个 task 列表,然后使用 asyncio 的 wait 方法即可执行,看下面的例子:
Python协程还不理解?请收下这份超详细的异步编程教程

文章插图
 
这里我们使用一个 for 循环创建了五个 task,组成了一个列表,然后把这个列表首先传递给了 asyncio 的 wait() 方法,然后再将其注册到时间循环中,就可以发起五个任务了 。最后我们再将任务的运行结果输出出来,运行结果如下:
Python协程还不理解?请收下这份超详细的异步编程教程

文章插图
 
可以看到五个任务被顺次执行了,并得到了运行结果 。
2.5 协程之间的链式调用我们可以通过使用 await 关键字,在一个协程中调用一个协程 。一个协程可以启动另一个协程,从而可以使任务根据工作内容,封装到不同的协程中 。我们可以在协程中使用 await 关键字,链式地调度协程,来形成一个协程任务流 。像下面的例子一样:
Python协程还不理解?请收下这份超详细的异步编程教程

文章插图
 
输出:
Python协程还不理解?请收下这份超详细的异步编程教程

文章插图
 
在上面,我们知道调用协程需要通过创建一个事件循环然后再去运行 。这里我们需要了解的是如果在协程里想调用一个协程我们需要使用 await 关键字,就拿上面的例子来说在 main 函数里调用协程 result1 和 result2 。那么问题来了:await 干了什么呢?
2.6 await 的作用我们前面使用到了许多次 await 那它的作用到底是什么呢?


推荐阅读