深入浅析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基础知识小结之集合
Nov 25 Python
python rsa 加密解密
Mar 20 Python
浅谈function(函数)中的动态参数
Apr 30 Python
python简易远程控制单线程版
Jun 20 Python
python无限生成不重复(字母,数字,字符)组合的方法
Dec 04 Python
简单了解Python3里的一些新特性
Jul 13 Python
python用win32gui遍历窗口并设置窗口位置的方法
Jul 26 Python
在Python中使用filter去除列表中值为假及空字符串的例子
Nov 18 Python
Python计算矩阵的和积的实例详解
Sep 10 Python
PyQt5结合matplotlib绘图的实现示例
Sep 15 Python
Python字典实现伪切片功能
Oct 28 Python
python开发人人对战的五子棋小游戏
May 02 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
asp和php下textarea提交大量数据发生丢失的解决方法
2008/01/20 PHP
setcookie中Cannot modify header information-headers already sent by错误的解决方法详解
2013/05/08 PHP
深入PHP运行环境配置的详解
2013/06/04 PHP
使用php清除bom示例
2014/03/03 PHP
tp5.0框架隐藏index.php入口文件及模块和控制器的方法分析
2020/02/11 PHP
JavaScript静态的动态
2006/09/18 Javascript
HTML中不支持静态Expando的元素的问题
2007/03/08 Javascript
Jquery Ajax学习实例5 向WebService发出请求,返回泛型集合数据的异步调用
2010/03/17 Javascript
JavaScript回调(callback)函数概念自我理解及示例
2013/07/04 Javascript
JavaScript电子时钟倒计时
2016/01/09 Javascript
AngularJS 2.0入门权威指南
2016/10/08 Javascript
Node.js Mongodb 密码特殊字符 @的解决方法
2017/04/11 Javascript
Vue.js 的移动端组件库mint-ui实现无限滚动加载更多的方法
2017/12/23 Javascript
剖析Angular Component的源码示例
2018/03/23 Javascript
详解一次Vue低版本安卓白屏问题的解决过程
2019/05/30 Javascript
ES6中异步对象Promise用法详解
2019/07/31 Javascript
JavaScript Array.flat()函数用法解析
2020/09/02 Javascript
[01:48]2018DOTA2亚洲邀请赛主赛事第二日五佳镜头 VG完美团战逆转TNC
2018/04/05 DOTA
Python编程入门的一些基本知识
2015/05/13 Python
Python中处理字符串之endswith()方法的使用简介
2015/05/18 Python
pandas修改DataFrame列名的方法
2018/04/08 Python
对python中字典keys,values,items的使用详解
2019/02/03 Python
pyqt5、qtdesigner安装和环境设置教程
2019/09/25 Python
Pytorch使用MNIST数据集实现CGAN和生成指定的数字方式
2020/01/10 Python
Django使用django-simple-captcha做验证码的实现示例
2021/01/07 Python
Pandas的数据过滤实现
2021/01/15 Python
自考生自我鉴定范文
2013/10/01 职场文书
教学实习自我评价
2014/01/28 职场文书
幼儿园校车司机的岗位职责
2014/01/30 职场文书
体育教师个人的自我评价
2014/02/16 职场文书
三八节标语
2014/06/27 职场文书
习近平在党的群众路线教育实践活动总结大会上的讲话
2014/10/21 职场文书
纪录片信仰观后感
2015/06/08 职场文书
装修安全责任协议书
2016/03/22 职场文书
Java Socket实现多人聊天系统
2021/07/15 Java/Android
springboot为异步任务规划自定义线程池的实现
2022/06/14 Java/Android