Python 异步(协程的用法)实例记录

Python 投稿 105300 1 评论

Python 异步(协程的用法)实例记录

event_loop 事件循环,相当于一个无限循环,我们可以把一些函数注册到这个事件循环上,当满足发生的条件时,就调用相应的处理方法。

coroutine 协程,指代协程对象类型,可以将协程对象注册到事件循环中,它会被事件循环调用。我们可以使用async关键字来定义一个方法,这个方法在调用时不会立即被执行,而是返回一个协程对象。

task 任务,这是对协程对象的进一步封装,包含协程对象的各个状态。

future 代表将来执行或没有执行的任务的结果,实际上和task没有本质区别。

# 定义协程,体验他和普通进程的不同之处
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对象。对此,我们也可以显式的进行声明,代码如下所示:

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

'''

# 定义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())

编程笔记 » Python 异步(协程的用法)实例记录

赞同 (81) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(1)个小伙伴在吐槽
  1. 看起来很炫酷。
    玫瑰小丑 2023-09-12 06:00 (1年前) 回复