Python中的协程与生成器的区别与联系
字数 780 2025-11-08 10:03:34
Python中的协程与生成器的区别与联系
让我们来探讨Python中协程与生成器的关系,这是一个理解异步编程基础的重要知识点。
1. 生成器的基本概念
生成器是一种特殊的迭代器,使用yield关键字实现。它的核心特性是能够暂停执行并保存状态,后续可以从中断处恢复执行。
示例:
def simple_generator():
print("开始")
yield 1
print("继续")
yield 2
print("结束")
gen = simple_generator()
print(next(gen)) # 输出:开始 然后 1
print(next(gen)) # 输出:继续 然后 2
2. 生成器向协程的演进
在Python 2.5中,生成器增加了.send()方法,使其能够接收外部传入的值,这标志着生成器开始具备协程的特性。
示例:
def coroutine():
print("启动")
x = yield "请发送值"
print(f"收到: {x}")
y = yield "请发送另一个值"
print(f"收到: {y}")
co = coroutine()
print(co.send(None)) # 启动协程,输出:启动 然后 "请发送值"
print(co.send(10)) # 输出:收到:10 然后 "请发送另一个值"
3. 协程的完整定义
协程是比生成器更通用的概念,它具有以下特征:
- 可以暂停执行(yield)
- 可以接收外部数据(.send())
- 可以向外发送数据(yield expression)
- 可以处理异常(.throw())
- 可以主动结束(.close())
4. 关键区别分析
数据流向:
- 生成器:主要单向产生数据(生产者)
- 协程:可以双向通信(既是生产者也是消费者)
设计目的:
- 生成器:主要用于创建迭代器,处理数据序列
- 协程:主要用于并发编程,管理执行流程
使用模式:
# 生成器模式(生产者)
def number_generator(n):
for i in range(n):
yield i
# 协程模式(消费者)
def average_calculator():
total = 0
count = 0
while True:
value = yield
if value is None:
break
total += value
count += 1
return total / count if count > 0 else 0
5. 现代协程:async/await
Python 3.5引入的async/await语法提供了更清晰的协程定义:
import asyncio
# 传统生成器协程
@asyncio.coroutine
def old_style_coroutine():
yield from asyncio.sleep(1)
# 现代原生协程
async def native_coroutine():
await asyncio.sleep(1)
6. 类型区分
Python 3.5+中明确区分了三种类型:
- 生成器函数:包含yield的函数
- 传统协程:使用@asyncio.coroutine装饰
- 原生协程:使用async def定义
7. 实际关系总结
协程和生成器在Python中是"实现关系"而非"替代关系":
- 生成器是协程的基础实现机制
- 所有生成器都可以作为简单的协程使用
- 但完整的协程需要更多的控制功能
- async/await提供了更符合协程语义的语法糖
理解这个关系有助于深入掌握Python的并发编程模型,为学习asyncio等异步框架打下坚实基础。