async
和 await
是 Python 中用于异步编程的关键字,它们使得编写异步代码更加简洁和直观,特别适用于 I/O 密集型任务和高并发场景。
基本概念 #
1. 异步函数定义 #
import asyncio
# 使用 async def 定义异步函数
async def say_hello():
print("Hello")
await asyncio.sleep(1) # 模拟异步操作
print("World")
# 运行异步函数
asyncio.run(say_hello())
2. 基本 await 使用 #
import asyncio
async def fetch_data():
print("开始获取数据")
await asyncio.sleep(2) # 模拟网络请求
print("数据获取完成")
return {"data": 123}
async def main():
result = await fetch_data() # 等待异步操作完成
print(f"获取到的数据: {result}")
asyncio.run(main())
高级用法 #
3. 并发执行多个任务 #
import asyncio
import time
async def task(name, delay):
print(f"任务 {name} 开始")
await asyncio.sleep(delay)
print(f"任务 {name} 完成")
return f"任务 {name} 结果"
async def main():
start_time = time.time()
# 同时启动多个任务
task1 = asyncio.create_task(task("A", 2))
task2 = asyncio.create_task(task("B", 1))
task3 = asyncio.create_task(task("C", 3))
# 等待所有任务完成
results = await asyncio.gather(task1, task2, task3)
end_time = time.time()
print(f"所有任务完成,耗时: {end_time - start_time:.2f}秒")
print(f"结果: {results}")
asyncio.run(main())
4. 使用异步上下文管理器 #
import asyncio
class AsyncResource:
async def __aenter__(self):
print("获取资源")
await asyncio.sleep(1)
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
print("释放资源")
await asyncio.sleep(0.5)
async def process(self):
print("处理资源")
await asyncio.sleep(2)
async def main():
async with AsyncResource() as resource:
await resource.process()
asyncio.run(main())
5. 异步迭代器 #
import asyncio
class AsyncCounter:
def __init__(self, stop):
self.current = 0
self.stop = stop
def __aiter__(self):
return self
async def __anext__(self):
if self.current >= self.stop:
raise StopAsyncIteration
await asyncio.sleep(0.5) # 模拟异步操作
self.current += 1
return self.current
async def main():
async for number in AsyncCounter(5):
print(f"计数: {number}")
asyncio.run(main())
实际应用场景 #
6. 异步网络请求 #
import aiohttp
import asyncio
async def fetch_url(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
urls = [
"https://httpbin.org/delay/1",
"https://httpbin.org/delay/2",
"https://httpbin.org/delay/3"
]
async with aiohttp.ClientSession() as session:
tasks = [fetch_url(session, url) for url in urls]
results = await asyncio.gather(*tasks)
for url, content in zip(urls, results):
print(f"{url}: {len(content)} 字符")
asyncio.run(main())
7. 异步数据库操作 #
import asyncio
import asyncpg
async def main():
# 连接数据库
conn = await asyncpg.connect(
user='user', password='password',
database='database', host='localhost'
)
# 执行查询
result = await conn.fetch('SELECT * FROM users WHERE active = $1', True)
for row in result:
print(f"用户: {row['username']}, 邮箱: {row['email']}")
# 关闭连接
await conn.close()
asyncio.run(main())
注意事项 #
- 异步函数必须使用
await
调用其他异步函数,否则不会实际执行 - 不能在同步函数中直接使用
await
,必须在异步函数中使用 - 使用
asyncio.run()
运行最外层的异步函数 - 避免在异步函数中使用阻塞式操作,这会阻止事件循环
- 可以使用
asyncio.create_task()
创建并发任务
async
和 await
关键字使得 Python 异步编程更加简洁和直观,特别适合处理 I/O 密集型任务,能够显著提高程序的并发性能和响应能力。