Python异步编程实战:让代码跑得比AI还快

0 阅读3分钟

大家好,我是船长。

最近Manus AI大火,让船长意识到一个趋势:AI在抢人类的执行工作,而Python异步编程,是让你代码"自己跑"的关键技术。

今天不聊AI,来聊技术。

什么是异步编程?

先从一个场景说起。

你要从10个API获取数据,传统的同步写法是这样的:


# 同步写法:一个个请求串行执行

for api in apis:

    data = requests.get(api)  # 每次等待网络返回

    results.append(data)

# 10个API × 每次1秒 = 10秒

改成异步后:


import asyncio

import aiohttp

async def fetch_all(apis):

    async with aiohttp.ClientSession() as session:

        tasks = [fetch(session, api) for api in apis]

        return await asyncio.gather(*tasks)

# 10个API并发执行 = 约1秒(取决于最慢那个)

异步的本质:IO等待时切换任务,而不是傻等。

场景1:批量API请求(最高频场景)

完整代码示例:


import asyncio

import aiohttp

import time

async def fetch_one(session, url, semaphore):

    async with semaphore:  # 限流:最多同时10个请求

        async with session.get(url) as response:

            return await response.json()

async def fetch_all(urls, max_concurrent=10):

    semaphore = asyncio.Semaphore(max_concurrent)

    async with aiohttp.ClientSession() as session:

        tasks = [fetch_one(session, url, semaphore) for url in urls]

        return await asyncio.gather(*tasks, return_exceptions=True)

# 使用

start = time.time()

results = asyncio.run(fetch_all(urls, max_concurrent=20))

print(f"耗时: {time.time() - start:.2f}秒")

关键点解读:

1. Semaphore限流:防止并发太高被API限流或打挂服务器

2. return_exceptions=True:单个请求失败不影响其他请求

3. ClientSession复用:建立连接池,复用TCP连接

场景2:异步文件操作

处理大量本地文件时,aiofiles是异步文件操作的首选:


import asyncio

import aiofiles

async def process_file(filepath):

    async with aiofiles.open(filepath, 'r') as f:

        content = await f.read()

    # 处理内容...

    return processed

async def batch_process(filepaths):

    return await asyncio.gather(*[process_file(f) for f in filepaths])

场景3:异步数据库操作

用databases库实现异步数据库操作,配合SQLAlchemy:


import asyncio

from databases import Database

db = Database("postgresql://localhost/mydb")

async def batch_insert(records):

    await db.connect()

    query = "INSERT INTO users(id, name) VALUES (:id, :name)"

    await db.execute_many(query, records)

    await db.disconnect()

场景4:异步定时任务

用APScheduler配合异步函数:


import asyncio

from apscheduler.schedulers.asyncio import AsyncIOScheduler

async def my_task():

    # 异步任务逻辑

    await fetch_and_process()

scheduler = AsyncIOScheduler()

scheduler.add_job(my_task, 'interval', hours=1)

scheduler.start()

性能对比实测

船长测试了100个API请求的性能对比:

**同步写法:**103秒(串行)

**异步写法(并发20):**8秒(提速12倍)

**异步写法(并发50):**4秒(提速25倍)

📌 测试环境:Python 3.11,100个模拟API(每个延迟0.5-1秒),MacBook Pro M2

常见坑与解决方案

坑1:忘记await

错误:result = fetch_data() # 这会返回协程对象

正确:result = await fetch_data() # 这才会执行并返回结果

坑2:在同步函数里调用异步函数

错误:def sync_func(): result = await async_func() # 会报错

正确:asyncio.run(async_func()) # 用run包装

坑3:忘记关闭ClientSession

用 async with 或确保 await session.close()

记住:异步不是银弹,CPU密集型任务用multiprocessing,IO密集型任务用asyncio。

总结

异步编程的核心场景:

  • 批量API请求(最高频)

  • 文件批量读写

  • 数据库批量操作

  • 定时任务调度

关键库:

  • aiohttp:异步HTTP客户端

  • aiofiles:异步文件操作

  • databases:异步数据库

  • asyncio:Python内置异步框架

学会异步,让你的Python代码"自己跑"。


作者:船长,数据分析师 + 职场观察者

微信公众号:CaptainTalk