对python中return与yield的区别详解


Posted in Python onMarch 12, 2020

首先比较下return 与 yield的区别:

return:在程序函数中返回某个值,返回之后函数不在继续执行,彻底结束。

yield: 带有yield的函数是一个迭代器,函数返回某个值时,会停留在某个位置,返回函数值后,会在前面停留的位置继续执行,直到程序结束

首先,如果你还没有对yield有个初步分认识,那么你先把yield看做“return”,这个是直观的,它首先是个return,普通的return是什么意思,就是在程序中返回某个值,返回之后程序就不再往下运行了。看做return之后再把它看做一个是生成器(generator)的一部分(带yield的函数才是真正的迭代器),好了,如果你对这些不明白的话,那先把yield看做return,然后直接看下面的程序,你就会明白yield的全部意思了:

def foo():
    print("starting...")
    while True:
      res = yield 4
      print("res:",res)
  g = foo()
  print(next(g))
  print("*"*20)
  print(next(g))

就这么简单的几行代码就让你明白什么是yield,代码的输出这个:

starting...
  4
  ********************
  res: None
  4

我直接解释代码运行顺序,相当于代码单步调试:

.程序开始执行以后,因为foo函数中有yield关键字,所以foo函数并不会真的执行,而是先得到一个生成器g(相当于一个对象)

.直到调用next方法,foo函数正式开始执行,先执行foo函数中的print方法,然后进入while循环

.程序遇到yield关键字,然后把yield想想成return,return了一个4之后,程序停止,并没有执行赋值给res操作,此时next(g)语句执行完成,所以输出的前两行(第一个是while上面的print的结果,第二个是return出的结果)是执行print(next(g))的结果,

.程序执行print("*"20),输出20个

.又开始执行下面的print(next(g)),这个时候和上面那个差不多,不过不同的是,这个时候是从刚才那个next程序停止的地方开始执行的,也就是要执行res的赋值操作,这时候要注意,这个时候赋值操作的右边是没有值的(因为刚才那个是return出去了,并没有给赋值操作的左边传参数),所以这个时候res赋值是None,所以接着下面的输出就是res:None,

.程序会继续在while里执行,又一次碰到yield,这个时候同样return 出4,然后程序停止,print函数输出的4就是这次return出的4.

到这里你可能就明白yield和return的关系和区别了,带yield的函数是一个生成器,而不是一个函数了,这个生成器有一个函数就是next函数,next就相当于“下一步”生成哪个数,这一次的next开始的地方是接着上一次的next停止的地方执行的,所以调用next的时候,生成器并不会从foo函数的开始执行,只是接着上一步停止的地方开始,然后遇到yield后,return出要生成的数,此步就结束。

def foo():
    print("starting...")
    while True:
      res = yield 4
      print("res:",res)
  g = foo()
  print(next(g))
  print("*"*20)
  print(g.send(7))

再看一个这个生成器的send函数的例子,这个例子就把上面那个例子的最后一行换掉了,输出结果:

starting...
  4
  ********************
  res: 7
  4

先大致说一下send函数的概念:此时你应该注意到上面那个的紫色的字,还有上面那个res的值为什么是None,这个变成了7,到底为什么,这是因为,send是发送一个参数给res的,因为上面讲到,return的时候,并没有把4赋值给res,下次执行的时候只好继续执行赋值操作,只好赋值为None了,而如果用send的话,开始执行的时候,先接着上一次(return 4之后)执行,先把7赋值给了res,然后执行next的作用,遇见下一回的yield,return出结果后结束。

.程序执行g.send(7),程序会从yield关键字那一行继续向下运行,send会把7这个值赋值给res变量

.由于send方法中包含next()方法,所以程序会继续向下运行执行print方法,然后再次进入while循环

.程序执行再次遇到yield关键字,yield会返回后面的值后,程序再次暂停,直到再次调用next方法或send方法。

这就结束了,说一下,为什么用这个生成器,是因为如果用List的话,会占用更大的空间,比如说取0,1,2,3,4,5,6…1000

你可能会这样:

for n in range(1000):
a=n

这个时候range(1000)就默认生成一个含有1000个数的list了,所以很占内存。

这个时候你可以用刚才的yield组合成生成器进行实现,也可以用xrange(1000)这个生成器实现

yield组合:

def foo(num):
    print("starting...")
    while num<10:
      num=num+1
      yield num
  for n in foo(0):
    print(n)

输出:

starting...
  1
  2
  3
  4
  5
  6
  7
  8
  9
  10
 xrange(1000):

  for n in xrange(1000):
    a=n

其中要注意的是python3时已经没有xrange()了,在python3中,range()就是xrange()了,你可以在python3中查看range()的类型,它已经是个<class ‘range'>了,而不是一个list了,毕竟这个是需要优化的。

以上这篇对python中return与yield的区别详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python中sys.argv函数精简概括
Jul 08 Python
Python实现处理逆波兰表达式示例
Jul 30 Python
在unittest中使用 logging 模块记录测试数据的方法
Nov 30 Python
python绘制漏斗图步骤详解
Mar 04 Python
解决py2exe打包后,总是多显示一个DOS黑色窗口的问题
Jun 21 Python
Python打开文件、文件读写操作、with方式、文件常用函数实例分析
Jan 07 Python
Pycharm debug调试时带参数过程解析
Feb 03 Python
Python流程控制常用工具详解
Feb 24 Python
python numpy矩阵信息说明,shape,size,dtype
May 22 Python
python 判断一组数据是否符合正态分布
Sep 23 Python
python pillow库的基础使用教程
Jan 13 Python
Python基于爬虫实现全网搜索并下载音乐
Feb 14 Python
python 子类调用父类的构造函数实例
Mar 12 #Python
python3中sorted函数里cmp参数改变详解
Mar 12 #Python
Python实现子类调用父类的初始化实例
Mar 12 #Python
python GUI框架pyqt5 对图片进行流式布局的方法(瀑布流flowlayout)
Mar 12 #Python
解决pycharm不能自动补全第三方库的函数和属性问题
Mar 12 #Python
Matplotlib使用Cursor实现UI定位的示例代码
Mar 12 #Python
PyCharm中Matplotlib绘图不能显示UI效果的问题解决
Mar 12 #Python
You might like
php 静态页面中显示动态内容
2009/08/14 PHP
php处理文件的小例子(解压缩,删除目录)
2013/02/03 PHP
PHP实现读取一个1G的文件大小
2013/08/24 PHP
php的mail函数发送UTF-8编码中文邮件时标题乱码的解决办法
2015/10/20 PHP
隐藏Nginx或Apache以及PHP的版本号的方法
2016/01/03 PHP
thinkPHP多表查询及分页功能实现方法示例
2017/07/03 PHP
JavaScript 数组运用实现代码
2010/04/13 Javascript
javascript 循环读取JSON数据的代码
2010/07/17 Javascript
jQuery滚动加载图片效果的实现
2013/03/06 Javascript
js实现在页面上弹出蒙板技巧简单实用
2013/04/16 Javascript
Node.js与PHP、Python的字符处理性能对比
2014/07/06 Javascript
js实现上传图片预览的方法
2015/02/09 Javascript
JavaScript获取页面中超链接数量的方法
2015/11/09 Javascript
Asp.Net之JS生成分页条的方法
2016/11/23 Javascript
C#微信小程序服务端获取用户解密信息实例代码
2017/03/10 Javascript
vue.js过滤器+ajax实现事件监听及后台php数据交互实例
2018/05/22 Javascript
微信小程序实现topBar底部选择栏效果
2018/07/20 Javascript
Vue+Element UI+Lumen实现通用表格分页功能
2019/02/02 Javascript
13 个npm 快速开发技巧(推荐)
2019/07/04 Javascript
使用VScode 插件debugger for chrome 调试react源码的方法
2019/09/13 Javascript
基于JQuery实现页面定时弹出广告
2020/05/08 jQuery
[27:39]Ti4 循环赛第二日 LGD vs Fnatic
2014/07/11 DOTA
[51:17]Mineski vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.22
2019/09/05 DOTA
Python中实现对list做减法操作介绍
2015/01/09 Python
利用Python的Flask框架来构建一个简单的数字商品支付解决方案
2015/03/31 Python
python实现批量监控网站
2016/09/09 Python
Python模块_PyLibTiff读取tif文件的实例
2020/01/13 Python
Python+Dlib+Opencv实现人脸采集并表情判别功能的代码
2020/07/01 Python
基于Python-turtle库绘制路飞的草帽骷髅旗、美国队长的盾牌、高达的源码
2021/02/18 Python
物业管理求职自荐信
2013/09/25 职场文书
五一服装活动方案
2014/01/11 职场文书
求职面试个人自我评价
2014/02/28 职场文书
贸易经济专业自荐书
2014/06/29 职场文书
海上钢琴师观后感
2015/06/03 职场文书
用Python爬取各大高校并可视化帮弟弟选大学,弟弟直呼牛X
2021/06/11 Python
win10系统计算机图标怎么调出来?win10调出计算机图标的方法
2022/08/14 数码科技