Python是如何实现生成器的原理
python中函数调用的实质原理:
python解释器(即python.exe)其实是用C语言编写的, 在执行python代码时,实际上是在用一个叫做Pyeval_EvalFramEx(C语言的函数)去执行代码中的函数,(实际上python中的程序实际上是运行在C语言之上的),运行此函数的时候,首先会在内存的堆区创建一个栈帧(stack frame),python中一切皆对象,在栈帧中间将要执行的代码编译成为字节码对象。 然后在栈帧的上下文中去运行字节码,可以用dis.dis()函数查看函数的字节码。
import dis
def foo():
bar()
def bar():
pass
print(dis.dis(foo)) 结果:
20 0 LOAD_GLOBAL 0 (bar)
2 CALL_FUNCTION 0
4 POP_TOP
6 LOAD_CONST 0 (None)
8 RETURN_VALUE
None
字节码解释:当foo调用子函数bar时候,又会创建一个栈帧,然后将函数的控制权交给新的栈帧,然后去运行bar的字节码,然后就有了两个栈帧了。因为所有的栈帧都是分配在堆的内存上,(函数调用完毕不会被立即回收)这就决定了栈帧可以独立于调用者存在,(即foo即使不存在了退出了也没有关系,只要有指针指向bar的栈帧,就可以对其进行控制)具体看一下代码:foo()调用完毕了之后,由于全局变量指向了bar中的栈帧对象,所以print(frame.f_code.co_name)语句输出产生当前栈帧对象的对象名,即bar,然后caller_frame = frame.f_back语句将调用者(foo)的栈帧对象获取到,然后打印出来,即foo。
import inspect
import dis frame = None
def foo():
bar()
def bar():
global frame
frame = inspect.currentframe()
foo()
print(frame.f_code.co_name)
caller_frame = frame.f_back
print(caller_frame) 输出结果:
bar
foo
图解如下:heap(堆区), recurse(递归,图中意思即foo递归调用了bar)
堆区的PyFrameObject表示生成的栈帧对象,f_code表示执行函数的字节码,f_back表示调用者函数的字节码。
生成器的实现原理:

def gen_fun():
yield 'a'
name = 'bobby1'
yield 'b'
age = 30
return 'frank'
import dis
gen = gen_fun()
print(dis.dis(gen)) #打印gen函数的字节码
print(gen.gi_frame.f_lasti)
print(gen.gi_frame.f_locals)
next(gen)
print(gen.gi_frame.f_lasti)
print(gen.gi_frame.f_locals)
next(gen)
print(gen.gi_frame.f_lasti)
print(gen.gi_frame.f_locals) 输出结果:
20 0 LOAD_CONST 1 ('a')
2 YIELD_VALUE
4 POP_TOP 21 6 LOAD_CONST 2 ('bobby1')
8 STORE_FAST 0 (name) 22 10 LOAD_CONST 3 ('b')
12 YIELD_VALUE
14 POP_TOP 23 16 LOAD_CONST 4 (30)
18 STORE_FAST 1 (age) 24 20 LOAD_CONST 5 ('frank')
22 RETURN_VALUE
None
-1
{}
2
{}
12
{'name': 'bobby1'}
真是因为有yield实现生成器函数,使得我们可以自由控制函数的运行于暂停,这个是协程实现的基础。
生成器的应用实例:用生成器函数读取一行的超大文件。
def yield_str(file, spilt):
buf = ''
while True: while spilt in buf:
pos = buf.index(spilt)
yield buf[:pos]
buf = buf[pos + len(spilt):]
chunk = file.read(100)
if not chunk:
yield buf
break
buf += chunk with open('txt.txt', encoding='utf-8') as file:
for i in yield_str(file, ','):
print(i)
Python是如何实现生成器的原理的更多相关文章
- Python 中生成器的原理
生成器的使用 在 Python 中,如果一个函数定义的内部使用了 yield 关键字,那么在执行函数的时候返回的是一个生成器,而不是常规函数的返回值. 我们先来看一个常规函数的定义,下面的函数 f() ...
- Python下探究随机数的产生原理和算法
资源下载 #本文PDF版下载 Python下探究随机数的产生原理和算法(或者单击我博客园右上角的github小标,找到lab102的W7目录下即可) #本文代码下载 几种随机数算法集合(和下文出现过的 ...
- Python学习之旅—生成器对象的send方法详解
前言 在上一篇博客中,笔者带大家一起探讨了生成器与迭代器的本质原理和使用,本次博客将重点聚焦于生成器对象的send方法. 一.send方法详解 我们知道生成器对象本质上是一个迭代器.但是它比迭代器对 ...
- Python源代码剖析笔记3-Python运行原理初探
Python源代码剖析笔记3-Python执行原理初探 本文简书地址:http://www.jianshu.com/p/03af86845c95 之前写了几篇源代码剖析笔记,然而慢慢觉得没有从一个宏观 ...
- 小白的Python之路 day4 生成器并行运算
一.概述 我们已经明白生成器内部的结构,其实就是通过像函数这样的东西实现的! 多线程和单线程:简单来说多线程就是并行运算,单线程就是串行运算 二.生成器执行原理 第一步:生成一个生成器 第二步:执行 ...
- python基础—迭代器、生成器
python基础-迭代器.生成器 1 迭代器定义 迭代的意思是重复做一些事很多次,就像在循环中做的那样. 只要该对象可以实现__iter__方法,就可以进行迭代. 迭代对象调用__iter__方法会返 ...
- Python之迭代器,生成器
迭代器 1.什么是可迭代对象 字符串.列表.元组.字典.集合都可以被for循环,说明他们都是可迭代的. from collections import Iterable l = [1,2,3,4] t ...
- python之迭代器与生成器
python之迭代器与生成器 可迭代 假如现在有一个列表,有一个int类型的12345.我们循环输出. list=[1,2,3,4,5] for i in list: print(i) for i i ...
- day13 python学习 迭代器,生成器
1.可迭代:当我们打印 print(dir([1,2])) 在出现的结果中可以看到包含 '__iter__', 这个方法,#次协议叫做可迭代协议 包含'__iter__'方法的函数就是可迭代函数 ...
随机推荐
- TJU ACM-ICPC Online Judge—1191 The Worm Turns
B - The Worm Turns Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu Su ...
- Eclipse Ctrl+Space 无法工作的问题
Window->preference->Keys 然后找到content Assist,然后重新设置为自己想要的Short cut 就好了
- JavaScript 的 4 种数组遍历方法: for VS forEach() VS for/in VS for/of
我们有多种方法来遍历 JavaScript 的数组或者对象,而它们之间的区别非常让人疑惑.Airbnb 编码风格禁止使用 for/in 与 for/of,你知道为什么吗? 这篇文章将详细介绍以下 4 ...
- 深海中的STL—nth_element
如果让你求区间第\(k\)大,你会怎么做呢? 主席树?确实是个不错的选择(不过像我这种垃圾还是乖乖打暴力吧) 在c++的stl库中,提供了nth_element这样一个函数 它的用法是nth_elem ...
- Dynamics 365 CE中AsyncOperationBase表记录太多,影响系统性能怎么办?
微软动态CRM专家罗勇 ,回复311或者20190311可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 本文主要是根据微软官 ...
- 如何解决升级到Dynamics 365后有很多的Sandbox的WorkerProcess并导致异常?
关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复254或者20170505可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong. ...
- 工作流引擎JFlow与activiti 对比分析(一)5种基本控制流模式的对比
为了更好的说明activiti 与jflow的两款工作流引擎的特点与区别,我们按照如下几个方面做一次全面的.客观的对比. 首先activiti是国外的一款开源的工作流程引擎,在国际上影响比较深远与广泛 ...
- OPC协议解析-OPC UA OPC统一架构
1 什么是OPC UA 为了应对标准化和跨平台的趋势,为了更好的推广OPC,OPC基金会近些年在之前OPC成功应用的基础上推出了一个新的OPC标准-OPC UA.OPC UA接口协议包含了之前的 ...
- Sublime Text 3 常用插件 —— SFTP
在 Win 下常用 Xftp 软件来和远程服务传递文件,但是要是在项目开发的时候频繁的将远程文件拖到本地编辑然后再传回远程服务器,那真是麻烦无比,但是Sublime中SFTP插件,它让这世界美好了许多 ...
- js计算剩余分钟
// 剩余时间提醒 function checkTime() { if (timeCompare()) { document.getElementById('distanceDeadline').in ...