📖 知识点
1. async 定义协程函数
在def前面加上async,这个函数就变成协程函数。
async def 函数名():
函数内部逻辑
普通函数:直接调用
func()就会执行代码协程函数:直接调用
func()不会运行函数内部代码,只会生成一个协程对象,需要异步运行器来执行
示例:
async def hello():
print("Hello 协程")
res = hello()
print(res) # <coroutine object hello at ...> 协程对象
2. await 关键字
写在协程函数内部,只能放在 async 函数里面。await + 可等待对象(协程、异步sleep、网络请求等)含义:遇到 IO 等待,让出当前任务执行权,不原地死等,交给调度器去跑别的任务。
⚠️ 重点禁忌
await不能写在普通 def 函数里面,语法报错await后面必须是可等待对象,不能直接跟普通 time.sleep (),要用异步版本asyncio.sleep()
基础完整示例
import asyncio
async def say_msg():
print("任务开始")
# 异步等待,等待期间可以切换其他任务
await asyncio.sleep(2)
print("任务结束")
💡 一句话记忆:async标记这是协程函数;await用来等待 IO、交出执行权。
⚔️ Kata 实战任务
任务需求:
导入 asyncio 库
使用 async 定义协程函数
study_task()函数内依次打印:
开始修炼御气术,await asyncio.sleep(2),打印御气修炼完毕调用函数,观察直接调用只会生成协程对象,不会执行打印
参考代码
import asyncio
# async 定义协程函数
async def study_task():
print("开始修炼御气术")
# await 异步等待
await asyncio.sleep(2)
print("御气修炼完毕")
# 直接调用协程函数,仅仅创建协程对象,代码不会执行
coro = study_task()
print(coro)
运行输出(地址每次运行不同):
<coroutine object study_task at 0x00000214E5678AC0>
你会发现:函数里面的 print 完全没有执行!下一节课学习
asyncio.run(),用来启动协程。
🧠 思考题
普通 time.sleep () 能不能放在 await 后面?为什么?
普通 def 函数里面能不能写 await?试猜想会报什么错?