一文掌握 Python 中的 asyncio 模块

文摘   2024-11-17 21:14   江苏  

什么是 asyncio

asyncio 是 Python 的一个异步 I/O 框架,用于编写并发代码,使用协程、任务和事件循环等概念。它允许你编写非阻塞的 I/O 操作,从而提高程序的性能。

为什么需要 asyncio

在处理 I/O 密集型任务时,传统的同步代码会因为等待 I/O 操作而阻塞,导致资源浪费。asyncio 通过异步编程模型,使得多个任务可以并发执行,提高程序的效率和响应速度。

基本概念

1. **协程 (Coroutine)**:协程是一种特殊的函数,可以暂停执行并在稍后恢复。在 Python 中,协程是通过 async def 定义的。 2. **事件循环 (Event Loop)**:事件循环是 asyncio 的核心,负责管理和调度任务。你可以通过 asyncio.run() 启动事件循环。 3. **任务 (Task)**:任务是 asyncio 中的可等待对象,代表一个正在运行的协程。任务可以被挂起和恢复。

示例 1:简单的协程

import asyncio

async def say_hello():
    print("Hello, world!")

# 启动事件循环并运行协程
asyncio.run(say_hello())

输出结果

Hello, world!

示例 2:并发执行多个协程

import asyncio

async def count(number):
    print(f"Counting {number}")
    await asyncio.sleep(1)  # 模拟 I/O 操作
    print(f"Finished counting {number}")

async def main():
    tasks = [count(i) for i in range(5)]
    await asyncio.gather(*tasks)  # 并发执行所有任务

asyncio.run(main())

输出结果

Counting 0
Counting 1
Counting 2
Counting 3
Counting 4
Finished counting 0
Finished counting 1
Finished counting 2
Finished counting 3
Finished counting 4

示例 3:使用 async withasync for

import asyncio

class AsyncCounter:
    def __init__(self, limit):
        self.limit = limit

    async def __aenter__(self):
        print("Starting counter")
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        print("Stopping counter")

    async def __aiter__(self):
        self.n = 0
        return self

    async def __anext__(self):
        if self.n < self.limit:
            current = self.n
            self.n += 1
            await asyncio.sleep(0.5)  # 模拟 I/O 操作
            return current
        else:
            raise StopAsyncIteration

async def main():
    async with AsyncCounter(3as counter:
        async for num in counter:
            print(f"Counting: {num}")

asyncio.run(main())

输出结果

Starting counter
Counting: 0
Counting: 1
Counting: 2
Stopping counter

高级概念

1. 取消任务

import asyncio

async def long_running_task():
    try:
        while True:
            print("Task is running")
            await asyncio.sleep(1)
    except asyncio.CancelledError:
        print("Task was cancelled")

async def main():
    task = asyncio.create_task(long_running_task())
    await asyncio.sleep(3)
    task.cancel()
    try:
        await task
    except asyncio.CancelledError:
        print("Task was cancelled")

asyncio.run(main())

输出结果

Task is running
Task is running
Task is running
Task was cancelled
Task was cancelled

2. 超时

import asyncio

async def long_running_task():
    await asyncio.sleep(10)
    print("Task completed")

async def main():
    try:
        await asyncio.wait_for(long_running_task(), timeout=5)
    except asyncio.TimeoutError:
        print("Task timed out")

asyncio.run(main())

输出结果

Task timed out

实战案例:并发请求多个网页

假设我们需要同时请求多个网页,可以使用 aiohttp 库来实现。

import asyncio
import aiohttp

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    urls = [
        "https://example.com",
        "https://python.org",
        "https://github.com"
    ]
    async with aiohttp.ClientSession() as session:
        tasks = [fetch(session, url) for url in urls]
        results = await asyncio.gather(*tasks)
        for i, result in enumerate(results):
            print(f"Response from {urls[i]}{len(result)} bytes")

asyncio.run(main())

输出结果(示例):

Response from https://example.com: 1256 bytes
Response from https://python.org: 45678 bytes
Response from https://github.com: 34567 bytes

总结

本文介绍了 Python 中的 asyncio 模块,包括基本概念、简单示例、高级概念以及一个实战案例。

好了,今天的分享就到这里了,我们下期见。如果本文对你有帮助,请动动你可爱的小手指点赞、转发、在看吧!

付费合集推荐

Python编程基础

Python办公自动化-Excel

微信公众号批量上传发布系统

文末福利

公众号消息窗口回复“编程资料”,获取Python编程、人工智能、爬虫等100+本精品电子书。

精品系统

微信公众号批量上传发布系统

关注我👇,精彩不再错过

手把手PythonAI编程
分享与人工智能和python编程语言相关的笔记和项目经历。
 最新文章