深入浅析Python中的yield关键字


Posted in Python onJanuary 24, 2018

前言

python中有一个非常有用的语法叫做生成器,所利用到的关键字就是yield。有效利用生成器这个工具可以有效地节约系统资源,避免不必要的内存占用。

一段代码

def fun():
for i in range(20):
 x=yield i
 print('good',x)
if __name__ == '__main__':
a=fun()
a.__next__()
x=a.send(5)
print(x)

这段代码很短,但是诠释了yield关键字的核心用法,即逐个生成。在这里获取了两个生成器产生的值,即0和1。分别由next函数和send()函数获得,这两个函数的区别我们后面会详细阐述。

关于__next__函数,这里先说明一下,我们可以利用__next__()这个函数持续获取符合fun函数规则的数,直到19结束。这段代码如下所示:

def fun():
for i in range(20):
 x=yield i
if __name__ == '__main__':
for x in fun():
 print(x)

这段代码的效果和下面这段代码是完全相同的

if __name__ == '__main__':
for i in range(20):
 x=yield i

for..in调用生成器算是生成器的基础用法,不过只会用for..in意义是不大的。生成器中最重要的函数是sent和__next__这两个函数,下面就针对这两个函数进行详细的阐述。

sent函数

这里特别强调了sent函数,因为sent函数没有那么直观。__next__函数很好理解,就是从上一个终止点开始,到下一个yield结束,返回值就是yield表达式的值。

例如在初始的那段代码里:

def fun():
for i in range(20):
 x=yield i
 print('good',x)

第一次调用__next__函数的时候,我们从fun的起点开始,然后在yield处结束,需要注意的是,赋值语句不会调用,此处yield i和含义和return差不多。

但是第二次调用__next__函数的时候,就会直接从上一个yield的结束处开始,也就是先执行赋值语句,然后输出字符串,进入下一个循环,直到下一个yield或者生成器结束

再次看初始的那段代码,可以发现第二次调用的时候没有选择使用__next__函数,而是使用了一个sent()函数。这里就需要注意,sent()函数的用法和__next__函数不太一样。sent()函数只能从yield之后开始,到下一个yield结束。这也就意味着第一次调用必须使用__next__函数。

sent()函数最重要的作用在于它可以给yield对应的赋值语句赋值,比如上面那一段代码中的

x=yield i

如果调用__next()__函数,那么x=None。但是如果调用sent(5),那么x=5。除了上述将的两个特征以外,sent和next并没有什么区别,sent函数也会返回yield表达式对应的值

next函数调用次可能有限

需要特别注意的是,尽管是生成器。但是next函数的调用次数可能是有限的。比如下面这段代码

def fun():
for i in range(20):
 x=yield i
 print('good',x)
if __name__ == '__main__':
a=fun()
for i in range(30):
 x=a.__next__()
 print(x)

生成器里的函数只循环了20次,但是next函数却调用了30次,这时候就会触发StopIteration异常。

总结

以上所述是小编给大家介绍的Python中的yield关键字,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python中正则表达式的详细教程
Apr 30 Python
Python中修改字符串的四种方法
Nov 02 Python
Python3删除排序数组中重复项的方法分析
Jan 31 Python
numpy.random模块用法总结
May 27 Python
Django发送邮件和itsdangerous模块的配合使用解析
Aug 10 Python
pytorch 指定gpu训练与多gpu并行训练示例
Dec 31 Python
PyQt5高级界面控件之QTableWidget的具体使用方法
Feb 23 Python
使用python检查yaml配置文件是否符合要求
Apr 09 Python
python求解汉诺塔游戏
Jul 09 Python
详解anaconda离线安装pytorchGPU版
Sep 08 Python
python实现过滤敏感词
May 08 Python
python实现局部图像放大
Nov 17 Python
Python3.6安装及引入Requests库的实现方法
Jan 24 #Python
pycharm+django创建一个搜索网页实例代码
Jan 24 #Python
Python数据类型中的“冒号“[::]——分片与步长操作示例
Jan 24 #Python
Sublime开发python程序的示例代码
Jan 24 #Python
安装python3的时候就是输入python3死活没有反应的解决方法
Jan 24 #Python
Python爬虫天气预报实例详解(小白入门)
Jan 24 #Python
Python实现PS滤镜碎片特效功能示例
Jan 24 #Python
You might like
批量修改RAR文件注释的php代码
2010/11/20 PHP
用php代码限制国内IP访问我们网站
2015/09/26 PHP
学习php设计模式 php实现桥梁模式(bridge)
2015/12/07 PHP
thinkphp3.x中display方法及show方法的用法实例
2016/05/19 PHP
php数据序列化测试实例详解
2017/08/12 PHP
yii2实现Ueditor百度编辑器的示例代码
2018/11/02 PHP
PHP生成二维码与识别二维码的方法详解【附源码下载】
2019/03/07 PHP
基于PHP实现微信小程序客服消息功能
2019/08/12 PHP
Javascript - HTML的request类
2006/07/15 Javascript
jquery ui dialog ie8出现滚动条的解决方法
2010/12/06 Javascript
FF火狐下获取一个元素同类型的相邻元素实现代码
2012/12/15 Javascript
圣诞节Merry Christmas给博客添加浪漫的下雪效果基于jquery实现
2012/12/27 Javascript
JS中的log对象获取以及debug的写法介绍
2014/03/03 Javascript
懒加载实现的分页&&网站footer自适应
2016/12/21 Javascript
BootStrap Tooltip插件源码解析
2016/12/27 Javascript
利用adb shell和node.js实现抖音自动抢红包功能(推荐)
2018/02/22 Javascript
react中使用swiper的具体方法
2018/05/15 Javascript
axios简单实现小程序延时loading指示
2018/07/30 Javascript
js实现整体缩放页面适配移动端
2020/03/31 Javascript
vue 出现data-v-xxx的原因及解决
2020/08/04 Javascript
python3 与python2 异常处理的区别与联系
2016/06/19 Python
教大家玩转Python字符串处理的七种技巧
2017/03/31 Python
Python科学画图代码分享
2017/11/29 Python
Python 离线工作环境搭建的方法步骤
2019/07/29 Python
Django框架教程之中间件MiddleWare浅析
2019/12/29 Python
使用tensorflow DataSet实现高效加载变长文本输入
2020/01/20 Python
python 中关于pycharm选择运行环境的问题
2020/10/31 Python
python复合条件下的字典排序
2020/12/18 Python
瑰珀翠美国官网:Crabtree & Evelyn美国
2016/11/29 全球购物
泰海淘:泰国king Power王权免税集团旗下跨境海淘综合型电商
2020/07/26 全球购物
阿里巴巴的Oracle DBA笔试题答案-SQL tuning类
2016/04/03 面试题
教师竞聘演讲稿
2014/05/16 职场文书
售房委托书
2014/08/30 职场文书
小学五年级(说明文3篇)
2019/08/13 职场文书
2019中秋节祝福语大全,提前收藏啦
2019/09/10 职场文书
Java基础之this关键字的使用
2021/06/30 Java/Android