在 Python 中,生成器(generator) 是一种特殊的“可迭代对象”,它能在运行过程中动态地产生数据,而不是一次性把所有数据加载到内存中。
生成器是理解 Python 高级用法(如协程、异步、惰性求值)的关键概念。下面我们分层讲清楚:
一、生成器的本质
生成器本质上是一种特殊的函数,通过 yield 语句来“逐步返回”值。
def count_up_to(n):
i = 1
while i <= n:
yield i
i += 1
调用 count_up_to(5) 不会立即执行函数体,而是返回一个生成器对象:
>>> gen = count_up_to(5)
>>> gen
<generator object count_up_to at 0x0000024E...>
每次调用 next(gen),函数会从上次中断的位置继续执行,直到再次遇到 yield:
>>> next(gen)
1
>>> next(gen)
2
>>> list(gen)
[3, 4, 5]
➡️ 特点总结:
• yield 暂停函数执行并返回值;
• 下次调用时从暂停处继续;
• 函数执行完后自动抛出 StopIteration;
• 内部状态(局部变量、循环计数)会被保留;
• 非常节省内存,适合大规模数据流。
⸻
二、yield 的理解
yield 相当于函数中的“暂停点”与“返回点”结合体。
你可以理解为:
return 是“一次性返回”,
yield 是“可以多次暂停返回”。
示例:
def demo():
print("Start")
yield 1
print("Middle")
yield 2
print("End")
g = demo()
next(g) # 输出 Start,返回 1
next(g) # 输出 Middle,返回 2
next(g) # 输出 End,抛 StopIteration
运行过程:
1. 第一次 next():执行到第一个 yield 停下;
2. 第二次 next():从上次停处继续;
3. 第三次:执行完函数,抛出结束异常。
⸻
三、yield from 的理解(语法糖)
yield from 是 Python 3 引入的语法,用来简化在生成器中“委托”另一个生成器的写法。
✅ 没有 yield from 的写法:
def generator_a():
for i in range(3):
yield i
def generator_b():
for x in generator_a():
yield x
yield 100
✅ 使用 yield from 的写法(等价简写):
def generator_b():
yield from generator_a() # 等价于上面 for 循环
yield 100
💡 优势
• 代码更简洁;
• 能自动传递 .send()、.throw()、.close() 等高级生成器方法;
• 能让“子生成器”与“外部调用者”直接通信(中间生成器无需转发)。
⸻
四、图解执行过程
调用方(调用 next/send) ───▶ 外层生成器 ───▶ 子生成器
▲ │
└───────── yield from ◀──┘
举个例子:
def sub_gen():
yield 1
yield 2
def main_gen():
yield 'start'
yield from sub_gen()
yield 'end'
for x in main_gen():
print(x)
输出:
start
1
2
end
➡️ yield from 会自动迭代 sub_gen() 中的每个 yield 值。
⸻
五、典型应用场景

⸻
六、一个完整示例:文件逐行读取
def read_large_file(file_name):
with open(file_name, 'r') as f:
for line in f:
yield line.strip()
for line in read_large_file("big.txt"):
print(line)
➡️ 文件按需读取,不会一次性加载全部内容。
⸻
七、总结口诀

122

被折叠的 条评论
为什么被折叠?



