Advertisement

【Python】一直没搞懂生成器是什么。。

阅读量:

生成器

上期我们讲解了迭代器:【Python】一直没搞懂迭代器是什么。。-博客
这期我们来讲讲它的好兄弟——生成器

生成器 (Generator)?

生成器是一种特殊的 迭代器 (Iterator)。
迭代器 是你可以逐个访问其元素的对象(比如在 for 循环中使用)。列表、元组、字典、字符串等都是可迭代对象,但它们不是迭代器本身。你可以通过调用 iter() 函数从可迭代对象获取迭代器。迭代器有一个 next() 方法,每次调用它会返回下一个元素,如果没有更多元素了,会引发 StopIteration 异常。
生成器 是一种创建迭代器 的简单而强大的方法 。它看起来像一个普通的函数,但关键区别在于它使用 yield 关键字来返回值,而不是 return

yield 是啥?

yield 是一个 Python 关键字,它有两个主要作用:

  1. 定义生成器函数: 任何包含 yield 语句的函数都会自动成为一个生成器函数 。调用这个函数不会立即执行函数体,而是返回一个生成器对象 (也就是一个迭代器)。

  2. 返回值并暂停: 当生成器函数的执行遇到 yield 语句时:

    • yield 后面的表达式的值会被返回给调用者(即正在迭代该生成器的代码)。
    • 函数的执行会在此处暂停 ,并保存当前的所有状态(包括局部变量)。
    • 当调用者请求下一个值时,函数会从暂停的地方恢复执行 ,直到遇到下一个 yield 或函数结束。
  3. 对比学习:yield vs return:

return彻底终止函数的执行 ,并返回一个值(或 None)。函数的状态不会被保存。

yield 只会暂停函数的执行,并返回一个值 。函数的状态会被保存,以便下次可以恢复。一个生成器函数可以有多个 yield 语句。

yield生成器,它们俩两个的关系?

  • 关系: yield 是用来创建生成器的语法核心 。一个函数因为包含了 yield 而成为生成器函数,调用它则得到生成器(迭代器)。

  • 打个比方~: *

生成器函数 (含yield 的函数): 扮演“蓝图”或“工厂”的角色,用于定义 如何按需生成一系列值。

yield 关键字: 扮演“暂停点”和“返回值发射器”的角色。它控制着值的生成和函数执行的暂停/恢复。

生成器对象 (调用生成器函数的结果): 扮演“迭代器”的角色。它实现了迭代协议(__iter__()__next__()),允许你通过循环或其他方式逐个获取由 yield 产生的值。

生成器函数–> 调用它不会返回return和yeild的内容,而是返回一个生成器对象

复制代码
    def gen(num):
    	while num > 0:
    		yield num
    		num -= 1
    	return
    g = gen(5)
    
    
    python
    
    

生成器对象

只有当你对这个生成器对象使用next函数的时候,他才开始真正它的函数本体

复制代码
    first = next(g)
    for i in g:
    	print(i)	
    
    
    python
    
    

从使用角度来看,生成器和迭代器几乎是完全一样的
我们正常定义的迭代器也就是 iterator,它是把这个迭代时候的状态保存在一个对象里的。而生成器也就是 generator,它实际上是把这个状态保存在了 frame

什么是frame

在 Python 中,frame(帧)是函数调用时的时上下文 ,属于 Python 虚拟机(PVM)的执行模型的一部分。

每个函数调用 会创建一个新的 frame,存储:

局部变量(locals()

当前代码位置(f_lasti,指向字节码的偏移量)

所属的代码对象(f_code

调用栈链(f_back,指向调用者的 frame

生成器的frameyield 时冻结,保存当前状态(包括局部变量、执行位置等),下次调用 next() 时恢复。

send

send 这个函数呢只是给你一个机制,让你可以去和你的generator做沟通和交流,可以改变他的一些状态

复制代码
    def  gen(num):
    	while num > O:
    	tmp = yield num
    	if tmp is not None:
    		num = tmp
    	num -= 1
    g = gen(5)
    first = next(g) # first = g.send(None)
    print(f"first: {first}")# 输入 5
    print(f"send: {g.send(10)}")
    for i in g:
    	print(i) # 输入 9 8 7 6 5 4 3 2 1
    
    
    Python
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/N6UQWfZnjaH9hOSV723eGElDgxiI.png)

对比

特性 迭代器(Iterator) 生成器(Generator)
状态保存位置 对象的属性(如 self.curr_node 函数的 frame(自动管理)
实现复杂度 需手动编写 __next__ 逻辑 yield 自动生成状态机
内存占用 通常更高(需显式存储状态) 更低(frame 按需保存)
适用场景 自定义复杂迭代逻辑(如树遍历) 惰性计算、大数据流
  • 生成器更轻量、更 Pythonic ,适合处理大数据或惰性计算场景。

全文PDF资源下载:【Python编程】深入解析迭代器与生成器的工作原理及应用场景:从基础概念到自定义实现了Python中的迭代资源-文库

关于作者

  • 大三小白新手菜鸟咸鱼本科生长期更新强烈建议不要关注

作者的其他文章

RAG调优|AI聊天|知识库问答

Agent

docker

Python

前端

nginx

好用插件

全部评论 (0)

还没有任何评论哟~