7、Python Asyncio异步编程【1】
单线程+多任务异步协程(重点)
协程的基本使用asyncio
1、特殊的函数
一个函数表示一组指定的操作。
import asyncio
from time import sleep
def get_request(url):
print('正在下载:',url)
sleep(2)
print('下载完成:',url)
get_request('www.baidu.com')
>>>
正在下载: www.baidu.com
下载完成: www.baidu.com
如果一个函数的定义被async关键字修饰后,则该函数就变成了一个特殊的函数。
async def get_request(url):
print('正在下载:',url)
sleep(2)
print('下载完成:',url)
get_request('www.baidu.com')
>>>
<coroutine object get_request at 0x0000021B165267C8>
- 特殊之处:
-
当特殊的函数被调用函数内部的实现语句不会被立即执行。
-
这个特殊函数被调用后会给我们返回一个协程对象。
2、协程
-
对象:协程对象 == 特殊函数 == 一组指定的操作
-
相当于 协程 == 一组指定的操作
async def get_request(url): print('正在下载:',url) sleep(2) print('下载完成:',url) #获取一个协程对象 c_object = get_request('www.baidu.com') print(c_object) #协程对象 >>> <coroutine object get_request at 0x0000011F757EAEC8>
3、任务
-
任务对象。所谓任务对象就是对协程对象进一步的封装。
-
任务对象 == 高级协程对象 == 特殊函数 == 一组指定的操作
async def get_request(url): print('正在下载:',url) sleep(2) print('下载完成:',url) #获取一个协程对象 c_object = get_request('www.baidu.com') #对协程c进行进一步封装,返回一个任务对象 task1 = asyncio.ensure_future(c_object) #获得了一个任务对象 >>> 正在下载: www.baidu.com 下载完成, www.baidu.com
-
-
给任务对象绑定回调:
-
task.add_done_callback(func)
import asyncio from time import sleep async def get_request(url): print('正在下载:',url) sleep(2) print('下载完成,',url) #创建事件循环对象 c_object = get_request('www.baidu.com') task = asyncio.ensure_future(c_object) #获得了一个任务对象 #事件循环对象目前是独立于协程和任务对象 loop = asyncio.get_event_loop() #创建了一个事件循环对象 #将任务对象注册装载到事件循环对象中并且启动事件循环对象 loop.run_until_complete(task)
上述代码无法获取特殊函数内部返回值
import asyncio from time import sleep #回调函数必须要有一个参数,表示的就是add_done_callback方法的调用者,就是任务对象本身 def callback(task): print('i am callback!,参数task=',task) print(task.result()) #获取特殊函数内部的返回值 #无法获取特殊函数内部的返回值 async def get_request(url): print('正在下载:',url) sleep(2) print('下载完成,',url) return url c_object = get_request('www.baidu.com')#创建事件循环对象 task = asyncio.ensure_future(c_object) #获得了一个任务对象 task.add_done_callback(callback)#给任务对象绑定回调函数 #事件循环对象目前是独立于协程和任务对象 loop = asyncio.get_event_loop() #创建了一个事件循环对象 loop.run_until_complete(task)#将任务对象注册装载到事件循环对象中并且启动事件循环对象 >>> 正在下载: www.baidu.com 下载完成, www.baidu.com i am callback!,参数task= <Task finished coro=<get_request() done, defined at E:/crawler/协程操作.py:8> result='www.baidu.com'> www.baidu.com
通过给任务对象绑定回调的方式获取特殊函数内部的返回值
- 回调函数的参数表示的就是任务对象本身
- task.result()返回的就是特殊函数内部的返回值
-
4、事件循环(核心)
- 一个容器对象。这个对象需要装载一个或者多个任务对象。生成的任务对象必须注册或者装载到事件循环对象中,然后如果事件循环对象启动后,就可以异步的将其内部装载的任务对象进行异步执行。