python协程之asyncio简单使用

描述

目录

简单的使用

相同和同步的对比

顺下载的例子

1.简单的使用

import asyncio

async def req1():
await asyncio.sleep(1)
print('执行 req1')
return 1


async def req2():
print('执行 req2')
return 2


async def main():
list = [req1(), req2()]
res = await asyncio.gather(*list)
'''
虽然,req2是先执行完的, 
但是res返回值的顺序, 还是跟list顺序保持一致
'''
print(res)


asyncio.get_event_loop().run_until_complete(main())
'''
结果:
执行 req2
执行 req1
[1, 2]
'''

2.相似和同时的对比

测试2个请求,同时触发请求执行的时间短,我是延迟让请求延迟返回

import asyncio
import time

import requests
from aiohttp import ClientSession


async def fetch(session, param):
async with session.get as resp:
data = await resp.json()
return data


async def req_async():
async with ClientSession() as session:
return await asyncio.gather(fetch(session, 2), \
fetch(session, 1))


def req():
session = requests.Session()
p1, p2 = 2, 1
return [
session.get.json(),
session.get.json()
]


async def main():
s1 = time.time()
v1 = await req_async()
s2 = time.time()
v2 = req()
print(f'异步请求时间:{round(s2-s1,1)}s \
响应结果:{[v["args"]["a"] for v in v1]}')
print(f'同步请求时间:{round(time.time()-s2,1)}s \
响应结果:{[v["args"]["a"] for v in v2]}')


if __name__ == '__main__':
asyncio.get_event_loop().run_until_complete(main())
'''
结果:
异步请求时间:3.2s 响应结果:['2', '1']
同步请求时间:7.9s 响应结果:['2', '1']
'''


3.相关下载的例子

看似请求、极大的文件限制、意外保存

async def download(sem, page: int, folder: str, session: ClientSession):
async with sem:
async with session.get(url, params={'page': page}) as resp:
async with aiofiles.open(f'{folder}/{page}.json', mode='w') as f:
await f.write(await resp.text())
return page


async def main():
# 请求url参数列表
url_pages = range(1, 5)
# 创建文件夹data
folder_name = 'data'
if not os.path.exists(folder_name):
os.makedirs(folder_name)
# 限制并发数量
sem = asyncio.Semaphore(50)
# 异步请求,并保存到文件
async with ClientSession(connector=TCPConnector(limit=5),
timeout=ClientTimeout(300)) as session:
tasks = []
for page in url_pages:
tasks.append(download(sem, page, folder_name, session))
result = await asyncio.gather(*tasks)
exp = set(url_pages)
act = set(result)
if exp == act:
print(f'全部下载完成')
else:
print(f'未成功:{exp - act},成功:{exp & act}')


if __name__ == '__main__':
asyncio.get_event_loop().run_until_complete(main())




审核编辑:刘清
 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分