高级特性:生成器(Generator)
🧩 为什么需要生成器?
在上一章中我们提到,为了按需获取数据,可以通过迭代器类来实现。然而,手动写 __iter__()
和 __next__()
方法比较繁琐。
Python 提供了更简洁的方式 —— 生成器(Generator),可以用普通函数语法生成一个迭代器。
🪄 什么是 yield
?
yield
是生成器函数的关键字。每次执行到 yield
就会暂停函数执行,并返回一个值,下一次迭代从上次暂停处继续。
✅ 最简单的生成器函数:
定 生成_数字():
循环 i 在 范围(3):
生成 i
# 使用
循环 数 在 生成_数字():
打印(数)
每次 for
循环都会触发 yield
返回一个值。生成器函数会自动生成一个支持 next()
的迭代器。
🔍 yield
和 return
有何不同?
对比项 | return | yield |
---|---|---|
用于 | 普通函数 | 生成器函数 |
返回 | 一次性返回结果并终止 | 多次暂停返回(可恢复) |
状态保留 | ❌ 每次都重新执行 | ✅ 保留上次的状态 |
用于 | 返回单个结果 | 惰性返回一组数据 |
🧪 示例:生成斐波那契数列
定 斐波那契(n):
a, b = 0, 1
计数 = 0
当 计数 < n:
生成 a
a, b = b, a + b
计数 += 1
对于 数 在 斐波那契(5):
打印(数)
运行结果是:
0
1
1
2
3
🚦 使用 next()
手动获取生成器值
定 gen():
生成 "A"
生成 "B"
g = gen()
打印(next(g)) # "A"
打印(next(g)) # "B"
打印(next(g)) # 报错:StopIteration
🧠 小技巧:生成器表达式
生成器也可以像列表推导式一样写成一行:
平方 = (x * x 循环 x 在 范围(5))
循环 i 在 平方:
打印(i)
相比列表推导式,这种写法不会一 次性创建整个列表,而是按需生成每个值,更省内存。
✅ 小结
yield
是生成器的核心,可创建一个惰性迭代器函数- 每次
yield
暂停执行,下一次继续从上次的位置开始 - 生成器非常适合处理大数据序列、无限序列或延迟计算
- 生成器表达式是更简洁的语法形式,效率高、语义清晰
📌 下一章我们将继续探索:装饰器(Decorator) —— 动态增强函数功能的魔法工具。如果你想现在就生成,我可以立即为你编写。