深入浅析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中__new__与__init__方法的区别详解
May 04 Python
详解Python中的Numpy、SciPy、MatPlotLib安装与配置
Nov 17 Python
Python简单实现阿拉伯数字和罗马数字的互相转换功能示例
Apr 17 Python
python自动查询12306余票并发送邮箱提醒脚本
May 21 Python
查看django执行的sql语句及消耗时间的两种方法
May 29 Python
python如何生成网页验证码
Jul 28 Python
pyqt5的QComboBox 使用模板的具体方法
Sep 06 Python
如何用Python破解wifi密码过程详解
Jul 12 Python
Pycharm中安装Pygal并使用Pygal模拟掷骰子(推荐)
Apr 08 Python
在keras中对单一输入图像进行预测并返回预测结果操作
Jul 09 Python
python能做哪些生活有趣的事情
Sep 09 Python
pycharm如何设置官方中文(如何汉化)
Dec 29 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
PHP 获取远程文件大小的3种解决方法
2013/07/11 PHP
简单介绍PHP非阻塞模式
2016/03/03 PHP
详谈PHP面向对象中常用的关键字和魔术方法
2017/02/04 PHP
一些有用的JavaScript和jQuery的片段分享
2011/08/23 Javascript
js冒泡法和数组转换成字符串示例代码
2013/08/14 Javascript
给文字加上着重号的JS代码
2013/11/12 Javascript
js出生日期 年月日级联菜单示例代码
2014/01/10 Javascript
jquery选择器大全 全面详解jquery选择器
2014/03/06 Javascript
构造函数+原型模式构造js自定义对象(最通用)
2014/05/12 Javascript
jQuery实现表格行上移下移和置顶的方法
2015/05/22 Javascript
JS中创建函数的三种方式及区别
2016/03/13 Javascript
JavaScript学习笔记之取数组中最大值和最小值
2016/03/23 Javascript
浅析Javascript中bind()方法的使用与实现
2016/05/30 Javascript
JavaScript原生数组Array常用方法
2017/04/06 Javascript
微信小程序--onShareAppMessage分享参数用处(页面分享)
2017/04/18 Javascript
浅谈node中的exports与module.exports的关系
2017/08/01 Javascript
Three.js开发实现3D地图的实践过程总结
2017/11/20 Javascript
Laravel整合Bootstrap 4的完整方案(推荐)
2018/01/25 Javascript
基于VUE实现的九宫格抽奖功能
2018/09/30 Javascript
Vue数据双向绑定底层实现原理
2019/11/22 Javascript
[34:10]Secret vs VG 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.24
2019/09/10 DOTA
Python实现简单状态框架的方法
2015/03/19 Python
django2 快速安装指南分享
2018/01/05 Python
解决windows下python3使用multiprocessing.Pool出现的问题
2020/04/08 Python
如何解决flask修改静态资源后缓存文件不能及时更改问题
2020/08/02 Python
实例讲解CSS3中的box-flex弹性盒属性布局
2016/06/09 HTML / CSS
澳大利亚婴儿喂养品牌:Cherub Baby
2018/11/01 全球购物
意大利时尚奢侈品店:D’Aniello Boutique
2021/01/19 全球购物
转党组织关系介绍信
2014/01/08 职场文书
小学教师事迹材料
2014/01/13 职场文书
鼓励运动员的广播稿
2014/02/08 职场文书
离婚协议书的书写要求
2014/09/17 职场文书
2015年医药代表工作总结
2015/04/25 职场文书
Java面试题冲刺第十八天--Spring框架3
2021/08/07 面试题
Python实现双向链表基本操作
2022/05/25 Python
MySQL数据库实验之 触发器和存储过程
2022/06/21 MySQL