Python Asyncio 高级应用指南
1. 什么是 Asyncio?
Asyncio 是 Python 3.4+ 引入的标准库,用于编写异步代码。它提供了协程、事件循环和异步 I/O 操作的支持,使我们能够编写高并发的网络应用和 I/O 密集型任务。
2. 基本概念
2.1 协程(Coroutine)
协程是一种特殊的函数,使用 async def 定义,可以使用 await 挂起执行,等待其他协程完成。
async def hello():
print("Hello")
await asyncio.sleep(1)
print("World")
2.2 事件循环(Event Loop)
事件循环是 Asyncio 的核心,负责调度协程的执行。它管理所有的异步操作,包括 I/O 操作、定时器和其他异步任务。
async def main():
await hello()
if __name__ == "__main__":
asyncio.run(main())
3. 高级特性
3.1 任务(Task)
任务是协程的包装器,允许我们并行执行多个协程。
async def task1():
await asyncio.sleep(2)
return "Task 1 done"
async def task2():
await asyncio.sleep(1)
return "Task 2 done"
async def main():
t1 = asyncio.create_task(task1())
t2 = asyncio.create_task(task2())
result1 = await t1
result2 = await t2
print(result1, result2)
3.2 Future
Future 是一个表示异步操作结果的对象。我们可以使用它来等待异步操作完成并获取结果。
async def main():
future = asyncio.Future()
# 在另一个协程中设置结果
async def set_result():
await asyncio.sleep(1)
future.set_result("Future completed")
asyncio.create_task(set_result())
result = await future
print(result)
3.3 并发执行
使用 asyncio.gather() 可以并发执行多个协程,并等待它们全部完成。
async def main():
results = await asyncio.gather(
task1(),
task2(),
task3()
)
print(results)
3.4 超时处理
使用 asyncio.wait_for() 可以为协程设置超时。
async def main():
try:
result = await asyncio.wait_for(task1(), timeout=1.5)
print(result)
except asyncio.TimeoutError:
print("Task timed out")
4. 实际应用
4.1 异步 HTTP 客户端
使用 aiohttp 库可以创建异步 HTTP 客户端,并发发送多个请求。
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
urls = [
"https://api.github.com/users/octocat",
"https://api.github.com/repos/octocat/Hello-World",
"https://api.github.com/repos/octocat/Spoon-Knife"
]
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url) for url in urls]
results = await asyncio.gather(*tasks)
for result in results:
print(len(result))
4.2 异步数据库操作
使用 aiosqlite 或 asyncpg 等库可以进行异步数据库操作。
import aiosqlite
async def main():
async with aiosqlite.connect("example.db") as db:
await db.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)")
await db.execute("INSERT INTO users (name) VALUES (?)" , ("Alice",))
await db.execute("INSERT INTO users (name) VALUES (?)" , ("Bob",))
await db.commit()
async with db.execute("SELECT * FROM users") as cursor:
async for row in cursor:
print(row)
4.3 异步 Web 服务器
使用 aiohttp 库可以创建异步 Web 服务器。
from aiohttp import web
async def handle(request):
name = request.match_info.get('name', "Anonymous")
text = f"Hello, {name}"
return web.Response(text=text)
async def main():
app = web.Application()
app.add_routes([web.get('/', handle),
web.get('/{name}', handle)])
runner = web.AppRunner(app)
await runner.setup()
site = web.TCPSite(runner, 'localhost', 8888)
await site.start()
print("Server started on http://localhost:8888")
await asyncio.Future() # 保持服务器运行
if __name__ == "__main__":
asyncio.run(main())
5. 最佳实践
- 使用 async/await 语法:避免使用旧的
@asyncio.coroutine装饰器。 - 合理使用任务:对于需要并行执行的操作,使用
create_task()创建任务。 - 使用上下文管理器:对于资源管理,使用
async with语句。 - 避免阻塞操作:在协程中避免使用阻塞操作,如
time.sleep(),应使用asyncio.sleep()。 - 错误处理:使用 try/except 捕获异步操作中的异常。
6. 总结
Asyncio 是 Python 中处理并发的强大工具,特别适合 I/O 密集型任务。通过掌握其高级特性,我们可以编写更加高效、可维护的异步代码。
在实际应用中,我们可以使用 Asyncio 构建高性能的网络应用、数据库操作和 Web 服务器,充分发挥 Python 的并发能力。
希望本文对你理解和应用 Asyncio 有所帮助!
846



被折叠的 条评论
为什么被折叠?



