对Python中yield的理解
最近要写一个程序,主要是用Python,之前也曾经接触过一些Python,但也只是基础,已经忘得差不多一干二净了!现在只能突击下啦!学到yield的时候遇到了不少问题,现在总结一下自己对yield的理解,希望和大家交流!
OK,今天的主题是yield,这是和Python中迭代相关的一个概念,所以一定要先了解迭代,例如,我们在for循环中一个可迭代的对象,比如一个列表ls=[1,2,3,4],我们用for来迭代访问他的话就是for x in ls: print x,之所以可以这样,是因为列表对象都实现了__iterator__方法,还有next方法,每次对ls迭代实际上就是调用一次next方法,而next方法会返回当前当前访问的数据然后再赋给接收它的x。我们就可以在循环体里面用x做我们想做的操作了!
def fun():print 'first'yield 1 ;④print 'second'yield 2 ;⑤print 'third'f=fun()
x=f.next() ;①
print x
f.next() ;②
f.next() ;③
运行的结果是:
first
1
second
third
Traceback (most recent call last):
File "D:/develop/Python26/e.py", line 12, in <module>
f.next()
StopIteration
如果你在IDLE里面直接打f回车你会看到现实f是一个generator,也就是说可以对他进行迭代访问,根据上面的程序及结果我们看看显式调用f的next方法看看对yield怎么处理,程序运行到①,程序就会进到fun中从最开是执行指导找到下一个yield语句也就是④,并把yield后的值作为next方法的返回值传出去,所以你会看到程序最先输出first,然后回到①,x接收到返回的值,再把x的值输出去所以会打印1。程序接着向下执行到②,然后跳到fun中从上次暂停的地方(也就是④)的下一条语句开始执行直到遇到下一个yield也就是⑤,这中间的都会执行,所以屏幕会打印出second然后把⑤处yield后的2作为next的返回值,但是②处并没有变量接收它,程序再执行到③,跳到fun中接着上次暂停的地方即⑤的下一句开始执行,直到下一个yield位置,但是我们看到fun中已经没有下一个yield了,所以这次迭代他会一直运行到结束,然后抛出个StopIteration异常,我们就会看到上面程序最后悔输出third然后再抛出一个异常。当然你也可以在上面代码中加上try...except...来捕获这个异常。
但是我们再看看在for中迭代包含yield的函数的情况(其实在for中每次还是调用fun1的next方法,但是这个next会和yield结合起来产生作用),比如有如下代码:
def fun1():print 'first' ;①yield 1 ;②print 'second' ;③yield 2 ;④print 'third' ;⑤yield 3 ;⑥print 'fourth' ;⑦for x in fun1(): ;⑧print x ;⑨
很多人都对上面这个代码的执行过程不是很清楚,我最开始也不懂,后来参考一些资料以及自己动手实验,大致知道了这个过程,那么接下来我就说说这个过程:首先之所以fun1可以这种方式迭代,原因是在函数体里面有yield方法,实际上这个fun1已经是一个generator,每一次迭代都是执行当前位置到下一个yield之间的代码,并把这个yield后面跟着的值最为返回传给x,如果你yield后面什么也不跟的话,那么默认是None,下面一步一步分析上面的代码:
当程序从⑧开始执行的时候第一次对fun1()进行迭代,程序会从①开始知道找到下一个yield也就是②,这中间的代码都会正常执行,所以first会被首先被打印出来,然后程序会在②处暂停,并把yield 1中的1传给本次迭代中的x,然后回去执行⑨,也就会把1(x等于1)输出出来,然后转回⑧开始第二次迭代,第二次迭代会从上一次迭代暂定的地方的下一个语句开始执行也就是③,直到遇到下一个yield语句,也就是④,这之间的代码都会执行,所以会打印出second,然后程序会再一次从这里暂停把④中yield后面的2传给本次迭代的x转到⑨,就会把2(x=2)输出出来,然后程序回到⑧开始第三次迭代,这次迭代会从刚才暂停的yield语句下面那行执行也就是⑤开始,直到遇到下一个yield语句也就是⑥,中间的语句都会执行,所以会打印出来third然后在⑥处暂停,并把⑥中yield后面的3传给本次迭代的x,然后转到⑨打印出3(x=3),然后再条到⑧开始第一次迭代(最后一次),程序从⑦开始执行直到找到下一个yield但是问题就来了,大家发现后面已经没有yield,那么这次迭代就会把⑦以及这之后的所有语句,然后会抛出一StopIteration异常,但是你在运行上面的代码并不会发现抛出异常,这其实是for替我们掩盖了而已(可以理解成for里面加了一个try…except…),他实际上就是通过StopIteration异常来结束迭代的。
通过上面两个程序大家应该对yield的工作过程有所了解了吧,那么还有一个东西需要说明一下,就是send函数,其实我们不仅可以从generator(这里指的就是含有yield的函数,下同)得到它yield的值,还可以给yield传值,send其实和next完成的工作基本都是一样的,只是send多了一个给他当前(这里的当前可以理解成上一次迭代时候暂停的地方)访问的yield表达式传递值,你在generator里面可以用赋值来接收send传进来的值。我们结合一个程序来看看:
def fun2():print 'first' yield 1 ;①print 'second' m=yield 2 ;②print m ;③print 'third' ;yield 3 ;④
print 'fourth'
yield 4h=fun2()
h.next() ;⑤
h.next() ;⑥
h.send("hello world!");⑦
h.next() ;⑧
结果是:
first
second
hello world!
third
fourth
程序从⑤开始迭代,第一次迭代的时候fun2运行到①处就暂停,打印内容和上个程序一个道理就不罗嗦了,我们继续从⑥开始迭代,从fun2的①处运行到下一个yield也就是②暂停,回到主程序到⑦,这次迭代是用send所以会给generator传值,从fun2的②处(注意这里的②就是当前的yield,也就是上一次迭代暂停的地方,如果要是用send传值的话也就是给②这个式子传)开始,这里用m接收send传来的值,然后在③处输出出来(hello world!),继续执行直到下一个yield④,回到主程序执行⑧,从④后面执行直到下一个yield,程序结束。
请大家认真理解一下就会发现两者的异同点了!
就写这么多了,这是第二篇文章,笔者也是刚刚接触Python所以,难免有所瑕疵和不足,希望大家多多包涵,多多指点。觉的我说的哪里不对,请评论告知,谢谢!
如需转载,希望大家注明原文出处链接以及说明作者Esfog,谢谢,分享是一种快乐!
http://www.cnblogs.com/Esfog/archive/2012/04/25/2470339.html
转载于:https://www.cnblogs.com/Esfog/archive/2012/04/25/2470339.html
对Python中yield的理解相关推荐
- python yield理解_对Python中Yield的理解
看到下面这段程序的时候,有点不明白这个yield到底是个啥东西,看了网上很多的博客,大致理解了yield的含义,所以记录下来. 要说yield首先要说python中的生成器,那么什么是生成器? 假设有 ...
- [翻译]Python中yield的解释
问题: Python中yield关键字的作用是什么?它做了什么? 例如,我想理解以下代码 def node._get_child_candidates(self, distance, min_dist ...
- python的yield是什么意思,python生成器是怎么使用的 python中yield是什么意思
python中return和yield怎么用的?两个有什么区别?你从未驯服过她,她只是在爱你的时候收起獠牙. yield yield是用于生成器.什么是生成器,你可以通俗的认为,在一个函数中,使用了y ...
- python中yield的用法(生成器的讲解)
2 理解说明yield与生成器 在Python中,使用yield的函数被称为生成器函数(generator function). 生成器有两种方法:next()和send(),都可以调用生成器 yie ...
- Python中yield和yield from的用法
yield 后面接的是 future 对象 调用方 委托生成器 yield from 直接给出循环后的结果 yield from 委托者和子生成器直接通信 yield from 直接处理stopIte ...
- Python中yield简单用法
Python中yield简单用法 你或许知道带有yield的函数在Python中被称之为generator,那何为 generator? 我们暂时抛开generator,先从一个常见编程题目开始,循序 ...
- python 中 yield 的使用
python中yield在函数中的使用 正是因为函数含有这个yield,所以,该函数不再是普通的函数,而是生成器函数(generator function).下面通过小例子来说明一下这个内置函数的特性 ...
- python中result的用法_关于Python中的列表理解及用法
在Python中,列表理解通常用于编写单行语句,这些语句通过可迭代对象进行迭代以创建新的列表或字典.本文首先介绍for循环如何在Python中工作,然后解释如何在Python中使用列表理解. Pyth ...
- python中raw是什么意思_对于Python中RawString的理解
对于Python中RawString的理解 发布于 2016-01-11 06:56:27 | 100 次阅读 | 评论: 0 | 来源: PHPERZ Python编程语言Python 是一种面向对 ...
- 对python中axis的理解
对 p y t h o n 中 a x i s 的 理 解 对python中axis的理解 对python中axis的理解 axis的实际含义是根据axis指定的维度进行连接,如矩阵m1的维度为(2, ...
最新文章
- azkaban获取上游的节点结果_Flink任务实时获取并更新规则
- python里的shell是什么_python中的shell操作
- 玩转SSRS第六篇---客户端报表进阶
- 旧题新做:从idy的视角看数据结构
- oracle values函数,Oracle文本函数简介
- shell 多个引号冲突_Html多个引号重叠使用冲突解决办法
- linux指法教程,Linux的vim的使用
- Onboard,迷人的引导页样式制作库
- Python爬虫项目:抓取智联招聘信息
- git pull VS git fetchmerge(good)
- 如何使用 DefaultServlet DefaultServletHttpRequestHandler 来处理静态资源
- 硬盘转速和平均寻道时间
- 在word中选择所有匹配查找内容的文档内容
- 宽带连接已断开 | 宽带拨号上网、连上几分之后自动断开|宽带连上一会儿就断
- 低价主机,怎么找性价比虚拟主机香港空间
- 掌握生成对抗网络(GANs),召唤专属二次元老婆(老公)不是梦
- EPICS AI记录
- android 广告视频,Android开屏视频广告
- linux下文件压缩、解压缩方法(tar)
- spring工作机制及原理
热门文章
- ant 日期组件中文_Vue3开源组件库,今天“它们”来了
- c语言随机数加密,TC伪随机数加密解决方法
- 机器学习- 吴恩达Andrew Ng Week6 Regularized Linear Regression and Bias/Variance知识总结
- 【网络入侵检测】K均值与层次聚类分析(sklearn,scipy,手写实现)
- 决策控制方法:sequential 规划、behavior-aware规划、端到端规划
- 152.乘积最大子序列
- 通过函数指针实现四则运算
- Multicarrier Interpretation of OTFS(OTFS的多载波解释)(7)⭐
- cmd静默运行_exe、msi、dos、bat等静默运行,后台运行,不弹窗的解决办法
- 深度学习框架PyTorch:入门与实践 学习(四)