# event_loop 事件循环,相当于一个无限循环,我们可以把一些函数注册到这个事件循环上,当满足发生的条件时,就调用相应的处理方法
# coroutine 协程,指代协程对象类型,可以将协程对象注册到事件循环中,它会被事件循环调用。我们可以使用async关键字来定义一个方法,这个方法在调用时不会立即被执行,而是返回一个协程对象
# task 任务,这是对协程对象的进一步封装,包含协程对象的各个状态
# future 代表将来执行或没有执行的任务的结果,实际上和task没有本质区别[Python] 纯文本查看 复制代码 # 定义协程,体验他和普通进程的不同之处
import asyncio
async def execute(x):
print('Number:',x)
coroutine = execute(1) # 返回协程对象
print('Coroutine:',coroutine)
print('After calling execute') # 调用 execute 后
loop = asyncio.get_event_loop() # 创建事件循环
loop.run_until_complete(coroutine) # 将协程对象注册到事件循环中,执行execute()
print('After calling loop')
# async定义的方法会变成一个无法执行的协程对象,必须将此对象注册到事件循环中才可以执行
# 在上述例子中,我们把协程对象coroutine传递给run_until_complete方法的时候,实际上它进行了一个操作,就是将coroutine封装成task对象。对此,我们也可以显式的进行声明,代码如下图所示:[Python] 纯文本查看 复制代码 import asyncio
async def execute(x):
print('Number:',x)
return x
coroutine = execute(1)
print('Coroutine:',coroutine)
print('After calling execute')
loop = asyncio.get_event_loop()
task = loop.create_task(coroutine)
print('Task:',task)
loop.run_until_complete(task)
print('Task:',task)
print('After calling loop')
# 定义loop对象后,紧接着调用他的create_task方法,将协程对象转化为task对象,随后打印一下,发现它处于pending状态。然后将task对象添加到事件循环中执行,并再次打印task对象,发现他的状态百年成了finished,同时看到其result变成了1,也就是我们定义的execute方法中的返回结果
'''
Coroutine: <coroutine object execute at 0x000002292A1FBDC0>
After calling execute
Task: <Task pending name='Task-1' coro=<execute() running at D:\爬虫开发实战代码\异步--协程的用法.py:23>>
Number: 1
Task: <Task finished name='Task-1' coro=<execute() done, defined at D:\爬虫开发实战代码\异步--协程的用法.py:23> result=1>
After calling loop
'''
[Python] 纯文本查看 复制代码 # 定义task对象还有另外一种方法,就是直接调用asyncio包中的ensure_future方法,返回结果也是task对象,这样的话我们就可以不借助loop对象。即使还没有声明loop,也可以提前定义好task对象,这种方式的写法如下:
import asyncio
async def execute(x):
print('Number:',x)
return x
coroutine = execute(1)
print('Coroutine:',coroutine)
print('After calling execute')
task = asyncio.ensure_future(coroutine)
print('Task:',task)
loop = asyncio.get_event_loop()
loop.run_until_complete(task)
print('Task:',task)
print('After calling loop')
# 绑定回调
import asyncio
import requests
async def request(): # 定义request方法,请求百度
url = 'https://www.baidu.com'
status = requests.get(url) # 获取状态码
return status
def callback(task): # 定义callback方法,接收参数,task对象
print('Status:', task.result()) # 打印task对象结果
# 以上就定义好了一个协程对象和一个回调方法。我们所期待的是,当协程对象执行完毕之后,就去执行声明的callback方法
coroutine = request()
task = asyncio.ensure_future(coroutine)
task.add_done_callback(callback) # add_done_callback调用callback函数名称时,task会自动传入一个task对象到callback函数中
print('Task:', task)
loop = asyncio.get_event_loop()
loop.run_until_complete(task)
print('Task:', task)
# 实际上,即使不使用回调方法,在task运行完毕之后,也可以直接调用result方法获取结果。代码如下所示:
import asyncio
import requests
async def request():
url = 'https://www.baidu.com'
status = requests.get(url)
return status
coroutine = request()
task = asyncio.ensure_future(coroutine)
print('Task:', task)
loop = asyncio.get_event_loop()
loop.run_until_complete(task)
print('Task:', task)
print('Task Result:', task.result())
# 多任务线程
import asyncio
import requests
async def request():
url = 'https://www.baidu.com'
status = requests.get(url)
return status
tasks = [asyncio.ensure_future(request()) for _ in range(5)] # 使用for循环创建了5个task,它们组成一个列表tasks
print('Tasks:', tasks)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks)) # 列表tasks首先传递给asyncio包的wait方法,再将其注册到事件循环中,就可以发起5个任务了
for task in tasks:
print('Task Result:', task.result())
|