Python中实现协程的三种方式
作者:归人云淡风轻
时间:2026-07-15
来源:正软商城
浏览:0
Python中协程通过单线程切换执行代码块,解决IO等待时线程闲置问题。实现方式有三种:早期yield关键字、Python3.4引入的asyncio装饰器、以及3.5后推荐的async/await写法,后者更简洁语义清晰,是现代协程标准做法。
### 协程
协程这个概念,说白了就是**用一个线程,让不同的代码块互相切换着执行**。它解决的核心痛点是什么?当线程遇到IO等待(比如网络请求、文件读写)时,不会傻等着,而是利用这段空闲时间去干点别的活——这才是协程的精髓所在。
下面这张图帮你快速理解三种实现方式:

**协程的意义:在一个线程中如果遇到IO等待时间,线程不会傻傻等,利用空闲时间再去干点其他事**
实现协程的主流方法主要有三种,按时间线来看:
1. `yield`关键字(早期玩法)
2. `asyncio`装饰器(Python 3.4 引入)
3. `async`/`await`关键字(Python 3.5 之后,正式推荐方案)
---
## 1. yield关键字
```python
def func1():
yield 1;
yield from func2() # 跳到func2函数里面
yield 2
def func2():
yield 3
yield 4
f1=func1()
for item in f1: # 每次循环,执行里面的yield
print(item)
```
如果一个函数里出现了`yield`关键字,我们就把它当作生成器函数。调用这个函数时,返回的是一个生成器对象。不过,**在现代协程实践中,基本不会用这种方式来写**——它更多是生成器的一种用法,了解一下就好,真正干活时不太推荐。
---
## 2. asyncio装饰器(3.4版本)
```python
import asyncio
@asyncio.coroutine
def func1():
print(1)
yield from asyncio.sleep(2) # 遇到IO耗时操作,自动化切换到tasks中的其他任务
print(2)
@asyncio.coroutine
def func2():
print(3)
yield from asyncio.sleep(2) # 遇到IO耗时操作,自动化切换到tasks中的其他任务
print(4)
tasks=[asyncio.ensure_future(func1()),
asyncio.ensure_future(func2())]
loop=asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
```
`asyncio`模块的特别之处在于:**遇到`yield from`后面的IO操作时,它不会死等,而是自动切换到任务列表中的其他任务**。这就好比要在网上下载一批图片,发送第一张图片的下载请求后,不必干等着响应,线程可以继续发送第二张、第三张的请求——你想想,这种“同时”处理多个等待的方式能省下多少时间。
---
## 3. async/await关键字(3.5版本后,推荐使用)
```python
import asyncio
async def func1():
print(1)
await asyncio.sleep(2) # 遇到IO耗时操作,自动化切换到tasks中的其他任务
print(2)
async def func2():
print(3)
await asyncio.sleep(2) # 遇到IO耗时操作,自动化切换到tasks中的其他任务
print(4)
tasks=[asyncio.ensure_future(func1()),
asyncio.ensure_future(func2())
]
loop=asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
```
这个版本和上面的`asyncio`装饰器实现的功能完全一样,只是**把装饰器`@asyncio.coroutine`换成了`async`,把`yield from`换成了`await`**。写法更简洁,语义更清晰,也是目前官方推荐的标准做法。如果你刚开始学协程,直接从`async/await`入手就好,没必要再纠结老版本的方式。
本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
github配置ssh key windows
本文详解如何在Windows环境中使用PowerShell生成SSH密钥对,配置ssh-agent自动加载私钥,并将公钥安全添加至GitHub账户,最后通过git remote set-url切换为SSH地址,解决每次操作需输入账号密码的问题。
backdrop和background区别
深入解析backdrop与background在网页开发及视觉设计中的区别。通过CSS代码示例,展示如何正确使用background设置元素背景,以及利用backdrop-filter创建弹窗遮罩模糊效果,避免概念混用。
ServBay安装配置详细教程与操作指南
新手入门 ServBay 本地开发环境,详解安装包下载、Dashboard 状态监控、Packages 组件安装、Services 服务控制及 Websites 项目配置。掌握 .servbay.config 版本管理与日志排查技巧,快速搭建稳定的 PHP、Node.js 等多语言开发环境。
NativeRest环境配置要求与完整操作教程
学习如何配置 NativeRest REST API 客户端。涵盖 Windows/macOS/Linux 安装后的工作区创建、环境变量管理、请求编辑及响应查看步骤,帮助开发者快速完成基础环境搭建与连通性测试。
查看更多