在 Python 中,如果你定义了一个协程函数(coroutine function),例如:
async def funa(): ...那么funa()本身并不会立即执行,而是返回一个协程对象(coroutine object)。要真正“启动”或“运行”这个协程函数,有以下几种常见方式:
✅ 1. 在另一个async函数中使用await
这是最常见的方式。你只能在async def定义的函数内部使用await:
async def caller(): await funa() # 启动并等待 funa 执行完成 # 然后你需要运行 caller()注意:
await只能在async def函数中使用。
✅ 2. 使用事件循环(Event Loop)直接运行协程(适用于顶层代码)
在 Python 3.7+ 中,可以使用asyncio.run()来运行协程(推荐方式):
import asyncio async def funa(): print("Hello from funa!") # 启动协程 asyncio.run(funa())⚠️
asyncio.run()应该只在程序顶层调用一次,不能嵌套使用。
✅ 3. 使用loop.create_task()或asyncio.create_task()(调度为后台任务)
这种方式会“启动”协程但不阻塞当前流程(即 fire-and-forget 或并发执行):
import asyncio async def funa(): print("Running funa") await asyncio.sleep(1) print("funa done") async def main(): task = asyncio.create_task(funa()) # 立即调度 funa 开始运行 await asyncio.sleep(0.5) print("Doing other things...") await task # 可选:等待它完成 asyncio.run(main())如果你不
await task,而主协程结束,funa可能被取消(取决于事件循环是否还在运行)。
✅ 4. 使用asyncio.gather()并发运行多个协程
import asyncio async def main(): await asyncio.gather(funa(), funb(), func()) asyncio.run(main())❌ 错误方式(不会启动函数)
- 直接调用
funa()而不加await或不传给事件循环:
这会生成一个未被使用的协程对象,Python 通常会发出警告(RuntimeWarning: coroutine 'funa' was never awaited)。funa() # 只返回一个 coroutine 对象,不会执行!
总结:启动async def funa()的合法方式
| 方式 | 是否启动 | 说明 |
|---|---|---|
await funa() | ✅ | 必须在async def内部 |
asyncio.run(funa()) | ✅ | 用于顶层启动 |
asyncio.create_task(funa()) | ✅ | 调度为并发任务 |
loop.create_task(funa()) | ✅ | 旧式写法(需手动获取 loop) |
asyncio.gather(funa()) | ✅ | 并发运行多个 |
仅funa() | ❌ | 仅创建协程对象,未执行 |