Python高阶专题:生成器以及生成器原理

本文深入解析Python中普通函数的调用流程及生成器的工作原理。解释了Python解释器如何通过C函数PyEval_EvalFrameEx执行函数,以及生成器函数在遇到yield关键字时的行为。生成器可以随时恢复执行,其状态保存在堆内存中,不遵循传统函数的调用顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Python普通函数的调用原理
def MainFunction() :  #主调函数
	MoudleFunction()
	pass
def MoudleFunction() : #被调函数
	pass

主调函数在执行过程中,主调函数一直持有控制权,当被调函数执行的时候,主调函数将控制权权交给被调函数,在被调函数执行期间,被调函数一直享有控制权直到执行完成之后释放控制权。

标准的Python解释器是通过c语言编写的,解释器通过一个c函数PyEval_EvalFrameEx 执行Python函数。其接受一个 Python 的堆栈帧对象,并在这个堆栈帧的上下文中执行 Python 字节码

155           0 LOAD_GLOBAL              0 (MoudleFunction)
              2 CALL_FUNCTION            0
              4 POP_TOP

156           6 LOAD_CONST               0 (None)
              8 RETURN_VALUE
None

当 PyEval_EvalFrameEx 遇到 CALL_FUNCTION 字节码的时候,它会创建一个新的 Python 堆栈帧,递归调用 PyEval_EvalFrameEx 来执行 bar。

Python 的堆栈帧是分配在堆内存中的,Python 解释器是个普通的 C 程序,所以它的堆栈帧就是普通的堆栈。但是它操作的 Python 堆栈帧是在堆上的。

2.Python生成器原理

前面提过Python在编译生成器函数为字节码的时候遇到yield关键字,会设置标注标注该函数为生成器函数。当调用生成器函数的时候,Python解释器看到标注,但是不会运行该函数而是会创建一个生成器。调用同一生成器函数的生成器都指向同一个代码对象【图】,但是个都有自己的堆栈帧。这个堆栈帧并不存在于实际的堆栈上,它在堆内存上等待着被使用

def ModuleFunction() :
    yield 1
module = ModuleFunction()
print(type(module)) #<class 'generator'>

在这里插入图片描述

生成器可以在任何时候被任何函数恢复执行,因为它的堆栈帧实际上不在堆栈上——它在堆(内存)上。生成器在调用调用层次结构中的位置不是固定的,它不需要遵循常规函数执行时遵循的先进后出顺序。生成器被是被解放了的,它像云一样浮动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值