Python Generator 数据状态和代码执行指令状态解析

一、Python generator 如何记忆数据状态和代码指令执行状态

Generators方法使用Python关键字yield而不是return来返回数据给调用者。下面是前面提到的一个方法,用于产生一个无限的数据序列:

如果使用return则意味着返回所有的数据(加载到内存中),之后这个方法执行就结束了。在上面的方法中,使用了yield来每次返回一个值给这个方法的调用者,与return不同之处在于,在返回值之后并不会退出方法的执行,相反,这个方法的状态会被记忆。通过这样的方式,当对一个generator对象调用next()方法时(可以在一个for循环中进行显式或者隐式的调用),通过yield产出的变量num是在递增的,然后又继续产出这个变量。换句话说,当调用者调用这个方法时,方法通过yield返回num值之后会进入“暂停”状态,等待调用者调用next()方法后,会执行语句num += 1进行递增,然后又通过yield返回变量num的值,接下来又进入“暂停”状态,并不会退出这个方法。所谓的“状态”就是指generator会知道当前的变量num值是什么(指数据状态),并且也记忆了关于执行代码的pointer(指指令状态),即需要执行语句num += 1。Python的coroutine机制就是基于此建立起来的。需要注意的是,Yield对象是存在于内存的堆(heap)中,所以才能反复循环使用。

在上面的方法中,while循环表达的意思就是执行代码的pointer不断在变,这个方法的状态不断在变。下面是调用这个方法的输出结果截图:

二、通过示例解析Python generator与 list的区别

在下面的例子中,第一个对象是通过中括号建立一个list,而第2个例子则是创建一个generator表达式。从输出结果可以很清楚看到list和generator对象的区别:

下面再来通过例子看下这两者之间的区别,我们把range(5)改为range(10000),通过循环分别创建一个list对象和一个generator对象,然后计算各自尺寸大小,看下输出效果:

在第1个例子中,返回结果是这个list的大小,合计为87616 bytes,而第2个例子返回的则是这个generator对象大小,可以看到只有112。两者比较,list对象大小是generator对象大小的700倍之多!

无论generators是基于一个方法还是一个表达式来构建,工作机制都是一样的。不同之处在于,使用表达式仅仅只是让你在一行就可以定义一个简单的generator,在generator对象内部的每个迭代中都会使用到yield。由此,Python的yield就成为了generators所支撑的各种功能的关键核心。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值