async函数中禁用time.sleep,须改用await asyncio.sleep();第三方同步库需通过run_in_executor封装;await仅适用于awaitable对象;__init__不可异步;asyncio.run()仅限脚本顶层调用。

async 函数里别混用 time.sleep
同步阻塞会直接卡死整个事件循环,time.sleep(1) 在 async 函数里等于“停掉所有协程”。这是新手最常踩的坑,现象是程序看似在跑,但其他任务完全不响应。
- 必须换成
await asyncio.sleep(1)—— 它让出控制权,允许其他协程运行 -
asyncio.sleep()是可取消的,而time.sleep()不是,这对超时和异常处理很关键 - 如果封装了第三方同步库(比如 requests),不能直接 await;得用
loop.run_in_executor()包一层,否则照样阻塞
await 后面只能跟 awaitable,不是所有函数都能加 await
常见错误是给普通函数或返回值加 await,比如 await get_user(),结果报 TypeError: object int is not awaitable 或更模糊的 RuntimeWarning: coroutine 'get_user' was never awaited。
- 只有返回
coroutine、Awaitable、Task或实现了__await__的对象才能await - 检查函数是否带
async def声明;没声明却想异步执行?那得自己用asyncio.create_task()或asyncio.ensure_future()包装 - 像
asyncio.gather()这类函数本身返回coroutine,所以要await asyncio.gather(...),而不是直接调用后就完事
不要在 __init__ 里写 async,构造函数不能是协程
Python 不允许 async def __init__(self),语法直接报错:SyntaxError: invalid syntax。有人试图绕过,比如在 __init__ 里调用 asyncio.run() 或启动新线程,结果引发事件循环冲突、嵌套循环崩溃,或者资源提前释放。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 初始化阶段需要异步操作?改用工厂函数:定义
async def create_instance(),显式await创建实例 - 或者把异步初始化逻辑拆到单独方法,比如
async def setup(self),由使用者主动调用 - 注意:
__aenter__/__aexit__才是异步上下文管理器的正确入口,不是__init__
asyncio.run() 只该用在脚本顶层,别在库函数里调
多次调用 asyncio.run() 会反复创建/关闭事件循环,在 Web 框架(如 FastAPI)、长期运行服务或单元测试中极易触发 RuntimeError: asyncio.run() cannot be called from a running event loop。
- 库代码应该只暴露协程函数,把事件循环管理交给上层应用
- 脚本入口(
if __name__ == "__main__")用asyncio.run(main())是安全且推荐的 - 测试时用
pytest-asyncio插件或手动asyncio.get_event_loop().run_until_complete(),避免run()嵌套
真正难的不是写出能跑的 async 代码,而是判断哪部分该异步、哪部分该同步、以及谁该负责启动和结束事件循环——这些边界一旦模糊,问题就会藏在并发量上来之后才爆发。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










