python协程

协程函数定义

协程函数以async开头

import asyncio
import time
#定义一个协程函数
async def func():
    # time.sleep(5)
    print('AAAAAAAAAAA')

#得到协程对象
res = func()
#创建事件循环
loop = asyncio.get_event_loop()
#将协程对象加入到事件循环中
loop.run_until_complete(res)
# #python 3.7 可直接使用asyncio.run方法
# asyncio.run(res)

await

'''await + 可等待对象(协程对象,Task对象,IO等待)'''
import asyncio
#创建协程函数
async def func():
    print('BBBB')
    response = await func_others()  #此处执行等待协程函数执行完毕,并返回值给response,之后继续往下执行
    print('CCCC',response)

async def func_others():
    print('DDDD')
    await asyncio.sleep(2)
    print('EEEE')
    return 'FFFF'
#创建事件循环
loop = asyncio.get_event_loop()
loop.run_until_complete(func())


运行结果:
在这里插入图片描述

Future对象

'''Task 继承Future对象,Task内部await结果处理基于future对象结果
future 有两种类型,一种是
'''
import asyncio
async def setValue(fut):
    '''延时2秒给fut对象赋值'''
    await asyncio.sleep(2)
    fut.set_result(2)

async def main():
    #获取当前事件循环
    loop = asyncio.get_running_loop()
    #创建一个任务,future对象,并指定函数参数
    fut = loop.create_future()
    #创建任务并将协程对象赋值给任务
    await loop.create_task(setValue(fut))

    #等待任务最终结果,没有结果一直等待下去
    data =  await fut
    print(data)
asyncio.run(main())

concurrent.futures.Tuture

'''
future对象有两种类型
1、通过事件循环创建future对象
2、concurrent.futures.Tuture 对象  ---使用线程池或者进程池来实现异步操作
'''

import time
from concurrent.futures import Future
from concurrent.futures.thread import ThreadPoolExecutor
from concurrent.futures.process import ProcessPoolExecutor

#定普通函数
def func(value):
    time.sleep(2)
    print(value)

if __name__ == '__main__':
    #创建一个线程数为5线程池
    pool = ThreadPoolExecutor(max_workers=5)
    for i in range(10):
        fut = pool.submit(func,1) #通过线程池的方式返回future
        print(fut)

task

'''task:在事件循环中添加多个任务'''
import asyncio
import time

async def func():
    print(1)
    #线程等待
    await asyncio.sleep(9)
    print(2)
    return 3

async def main():
    print('---START---')
    #创建task任务列表
    task_list = [
        asyncio.create_task(func(),name='test_01'),
        asyncio.create_task(func(),name='test_02')
    ]
    print('---END---')
    done,pending = await asyncio.wait(task_list,timeout=None)
    print(done)
asyncio.run(main())  #python3.7写法

打印结果:
在这里插入图片描述
task优化写法

    task_list = [
        #直接在此处创建协程对象
        func(),
        func()
    ]
    done,pending = asyncio.run(asyncio.wait(task_list))
    print(done)

两种不同类型的future结合使用,在不支持异步的模块中使用异步编程(常用)

'''协程异步 + requests(不支持)场景(协程函数中调用普通函数)'''
import time
import asyncio
import requests
import concurrent.futures

def func():
    #某个耗时操作
    time.sleep(2)
    return 2

async def main():
    loop = asyncio.get_running_loop()
    #第一步:内部会先调用 ThreadPoolExecutor的submit方法去申请一个线程执行func函数,并返回一个concurrent.futures.Future对象
    #第二部:调用asyncio.wrap_futures.future方法将concurrent.future.Future对象包装成为asyncio.future对象
    #因为concurrent.future.Future对象不支持await方法,所以需要包装
    fut = loop.run_in_executor(None,func)
    result = await fut
    print('default thread pool',result)

#案例
async def dowmload_images(url):
    print('开始下载:%s'% url)
    #发送IO请求
    loop = asyncio.get_event_loop()
    #requests模块不支持异步操作,故使用线程池来实现
    future = loop.run_in_executor(None,requests.get,url)
    response = await future
    print('%s:下载完成...',url)
    #本地存储
    file_name = url.split('_')[-1]
    with open(file_name,'wb') as f:
        f.write(response.content)



if __name__ == '__main__':
    # asyncio.run(main())
    url_list = ['https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608562578327&di=3a5b6a9e81dbfffeb9591331b98f1364&imgtype=0&src=http%3A%2F%2Fpic.jj20.com%2Fup%2Fallimg%2F1113%2F041620103S8%2F200416103S8-4-1200.jpg',
                'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608562578327&di=3a5b6a9e81dbfffeb9591331b98f1364&imgtype=0&src=http%3A%2F%2Fpic.jj20.com%2Fup%2Fallimg%2F1113%2F041620103S8%2F200416103S8-4-1200.jpg',
                'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608562578327&di=3a5b6a9e81dbfffeb9591331b98f1364&imgtype=0&src=http%3A%2F%2Fpic.jj20.com%2Fup%2Fallimg%2F1113%2F041620103S8%2F200416103S8-4-1200.jpg'
                ]
    #创建协程
    tasks = [dowmload_images(url) for url in url_list]
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(tasks))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值