
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、你知道python中的函数、生成器的工作原理吗?1.python中函数的工作原理 python的说明器,也就是python.exe(c编写)会用pyeval_evalframex(c函数)运行foo()函数 首先会创建一个栈帧(stack frame),在栈帧对象的上下文里面去运行这个字节码。 可以尝试着去打印foo的字节码: 关于字节码的说明: 打印bar的字节码: 这个字节码全局是唯一的,函数是全局唯一的,然后在函数里面会调用另外一个函数。 当foo调用函数bar,又会创建一个栈帧,然后将这个函数的控制权交给这个栈帧。 全部的栈帧都分配在内存中,它不是放在栈的内存上,而是放在堆的内存上,你
2、不去释放它就会向来存在我们的内存当中。 这就打算了栈帧可以自立于调用者存在,比如就算函数不存在了,只要有指针指向bar这个栈帧,就可以对其举行控制。 (python中一切皆对象,栈帧也是对象,是一个字节码对象) 2.生成器的实现原理 在静态语言中,函数调用的时候是一个栈的形式,函数调用尽成之后栈就会被销毁。 下面是函数的调用过程: pyeval_evalframeex会创建一个foo的栈帧对象,这个对象里面有两个属性。f_back为none,由于没有上层函数,f_code指向foo的字节码 同时pyeval_evalframeex也会创建一个bar的栈帧对象,f_back指向foo,f_cod
3、e指向bar的字节码。 最大的特点就是栈帧对象存在于堆内存中,这样生成器才有实现的可能。 当python说明器在读取gen_fun()这个函数的时候,发觉yield关键字就会将其标志为生成器函数。 gen_func() 当我们来调用这个函数的时候,就会返回一个生成器对象。 这个生成器对象是将pyframe做了一层封装。 在pyframeobject和pycodeobject上面又封装了一层pygenobject,就是python的生成器对象。 pygenobject中gi_frame属性指向pygrameobject,gi_code属性指向pycodeobject。 pyframeobject
4、又有f_lasti和f_locals属性。 f_lasti会指向最近执行的这个代码。 可以尝试打印字节码: 查看结果: 这里面可以看到有两次yield。当我们每一次对生成器做一次调用的时候,它碰到yield就会停止。 停止了之后,就会记录f_lasti(位置)和f_locals(变量)这两个值。 可以尝试着调用打印取每一个值,f_lasti和f_locals的变幻 与上方字节码是一样的。 这样囫囵生成器对象就存在与堆内存中,可以自立存在,每次执行一次函数,就会生成一个栈帧对象。 我们可以在任何地方,只要能拿到这个栈帧对象就能够往前走。这也是python中协程的一个理论基础。 此时我们可以知道为什么生成器是一个一个返回。 3.pyc文件 当你在执行python代码的时候,会发觉执行名目下面会浮现.pyc文件。 r1.pyc是一个二进制文件,当执行的文件中存在包的引入就会编译生成二进制文件。 当python程序运行时,编译的结果则是保存在位于内存中的pycodeobject中,当python程序运行结束时,python说明器则将pycodeobject写回到pyc文件中。 当python程序其次次运行时,首先程序会在硬盘中寻觅pyc文件,假如找到,则挺直载入,否则就重复上面的过程。
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论