异步编程的救星
用Asyncio让你的程序飞起来
写程序最烦的就是要等待,不管是调接口、读文件还是查数据库,程序总得干等着结果出来才能继续干活。要是能让程序在等的时候顺便做点别的事那该多好!这就是 异步编程 要解决的问题,而Asyncio就是Python世界里最好用的异步编程工具。
打个简单的比方,平时我们写的程序就像是个按部就班的机器人,一件事一件事排队做。而异步编程就像是个会“多线程”思考的超级管家,他可以一边煮着咖啡,一边查看邮件,还能顺便给花浇水。
来看个最基础的例子:
import asyncio
async def make_coffee():
print(“开始煮咖啡...”)
await asyncio.sleep(3) # 模拟煮咖啡的时间
print(“咖啡煮好了!”)
async def check_email():
print(“查看邮件中...”)
await asyncio.sleep(2) # 模拟收邮件的时间
print(“邮件看完了!”)
async def main():
await asyncio.gather(make_coffee(), check_email())
asyncio.run(main())
❗温馨提示:async
和await
是异步编程的关键字,忘记加这俩,代码就废了。
咱们写异步代码最常用的就是协程。协程说白了就是能暂停执行的函数,用async def
来定义。写法上和普通函数差不多,就是前面多个async
:
async def download_file(file_name):
print(f“开始下载{file_name}”)
await asyncio.sleep(1) # 假装在下载
print(f“{file_name}下载完成”)
有时候咱们想同时执行好几个异步任务,asyncio.gather
就派上用场了:
async def main():
files = ['文档.pdf', '音乐.mp3', '视频.mp4']
tasks = [download_file(f) for f in files]
await asyncio.gather(*tasks)
来个真实点的例子,写个异步网络爬虫:
import asyncio
import aiohttp
async def fetch_url(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
async def main():
urls = [
'http://example.com/page1',
'http://example.com/page2',
'http://example.com/page3'
]
results = await asyncio.gather(*[fetch_url(url) for url in urls])
for url, html in zip(urls, results):
print(f“抓取到 {url} 的内容长度:{len(html)}”)
❗温馨提示:用异步代码别忘了安装对应的异步库,比如这里的aiohttp
。
写异步代码最容易掉坑里的就是忘记await
。就像这样:
async def wrong_way():
asyncio.sleep(1) # 错误!没加await
async def right_way():
await asyncio.sleep(1) # 正确!
还有个坑是在异步函数里面调用普通的阻塞函数,这样异步就失去意义了。得想办法找到对应的异步版本,比如用aiofiles
代替open
,用aiohttp
代替requests
。
异步编程确实让代码写起来更爽,程序跑起来更快。不过也别啥都用异步,有些简单的小程序用同步的方式写反而更清晰。关键是要知道啥时候该用,啥时候不该用。
代码写多了就会发现,异步编程就像是给你的程序装上了翅膀,让它能同时处理多个任务。掌握了这个技能,以后写起高性能的程序来就轻松多了!