Python 生成器函数详解
2026/9/12 20:04:52 网站建设 项目流程

那么, 在特定的情境当中, 存在着这样一种极为神奇的函数, 它就是生成器函数, 它呢, 既好像函数, 又仿佛是一个能够记住中间状态的魔法盒子 , 在处理大数据流之际, 它的好用程度尤为显著!

这篇文章, 会一步步引领你弄明白, 生成器函数究竟是什么东西, 有什么作用, 该如何去写, 又该怎么加以使用。

参考文章: 迭代器 | 简单一点学习 .me

生成器函数究竟是什么, 普通函数和生成器函数有何不同, yield到底是什么, 该怎么使用, 用for去遍历生成器函数时yield与之有什么区别, 用next()手动调用生成器会怎样, yield from如何更优雅地嵌套生成器, 生成器函数有哪些应用场景, 有什么需要注意的事项以及陷阱, 小结和写法建议又是什么, 什么是生成器函数。

生成器函数, 是一种借助yield却并非使用返回值的函数。其发挥的作用在于, 每一次进行调用时会返回一个值, 然而并不会退出该函数, 而是会在当下位置暂停, 下一次会继续从暂停的地方开始执行。

举个栗子:

def my_gen(): yield 1 yield 2 yield 3

调用这个函数时,它不会立马执行,而是返回一个生成器对象:

g = my_gen() print(g) #

2. 普通函数 vs 生成器函数特性普通函数生成器函数

使用关键字

yield

返回什么

一次性返回所有结果

每次返回一个值

内存消耗

可能较大

非常省内存

可暂停执行

不可以

可以暂停并恢复执行

3. yield 是啥?怎么用?

产出, 是生成器函数之中, 最为关键的点。它能够使得函数处于暂停的状态, 将相应的值传递出去, 之后等待获取下一次的调用指令。

def count_up_to(max): count = 1 while count <= max: yield count count += 1

用法:

for num in count_up_to(3): print(num)

输出:

1 2 3

每次, 产出一个值, 下一轮, 从产出的下一行相邻处, 持续按照规则运行, 接着运行。

4. 用 for 遍历生成器函数

这属于最为常见的用法, 实际上其背后所蕴含的内容乃是迭代器相关原理, 也就是借助 next() 方法一点一点地去获取内容, 然而你并不需要去理会这些内容, 只要如同遍历列表那般去使用便可以了:

def gen_words(): yield "hello" yield "world" for word in gen_words(): print(word)

输出:

hello world

5. yield 与 的区别对比点

暂停函数

否(直接结束函数)

返回值

一次一个

一次性全部

多次调用

每次从上次 yield 后继续

每次都重新开始

例子对比:

def func_return(): return 1 return 2 # 永远不会执行 def func_yield(): yield 1 yield 2

6. 用 next() 手动调用生成器

可以不用 for,直接用 next() 来一个一个取值:

g = (x * 2 for x in range(3)) print(next(g)) # 0 print(next(g)) # 2 print(next(g)) # 4 # print(next(g)) # StopIteration

对生成器函数也是一样:

def simple_gen(): yield "A" yield "B" g = simple_gen() print(next(g)) # A print(next(g)) # B

7. yield from:更优雅地嵌套生成器

若在一个供产生的器具里调用另外一个供物产产生的器械, 能够以产生出息从这里开始替代数量众多的用于循环的器械。

传统写法:

def outer(): for val in [1, 2, 3]: yield val

更简洁写法:

def outer(): yield from [1, 2, 3]

也支持嵌套生成器函数:

def gen1(): yield "A" yield "B" def gen2(): yield from gen1() yield "C" for x in gen2(): print(x)

输出:

A B C

8. 生成器函数的应用场景

生成器函数在处理大量数据或流式数据时非常好用:

场景1:按行读取大文件

def read_large_file(path): with open(path, "r") as f: for line in f: yield line.strip()

场景2:无限序列(如斐波那契)

def fib(): a, b = 0, 1 while True: yield a a, b = b, a + b
f = fib() for _ in range(10): print(next(f))

场景3:模拟数据流或日志流

import time def log_stream(): count = 0 while True: yield f"log line {count}" count += 1 time.sleep(1)

9. 注意事项与陷阱10. 小结和写法建议

关键词记牢:

什么时候用生成器函数?

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询