python进阶学习之 yield
2016-06-05 00:00
465 查看
摘要: 有助于你写出pythonic的code
对上述程序进行简单的分析:
执行输出的结果:yield value,
generator = gen() , 创建一个生成器, (含有yield的函数体, 其函数调用的结果就是生成一个生成器, 不会执行其函数体。)
generator.next(), 只有当生成器的next函数被第一次触发, 函数体才会被执行, 到第一个yield处挂起。程序稍作修改来验证一下:
执行结果:
created a generator
enter gen()
yield value
如果生成器的next函数被第二次触发(再次例子中), 由于没有yield了, 会在函数体执行结束之后抛出异常。
执行结果:
yield value
StateA None
Traceback (most recent call last):
File "yield-sample.py", line 9, in <module>
print generator.next()
StopIteration
b = (yield "yield value") , 从上述的执行结果中看, b的值为None, 同时应该注意到, 复制动作是在第二次next的时候被调用到的。
我们再想, 如何让yield expression有返回值, 并且此返回值是从外围穿入进去的, 这正是generator.send(value)要做的事情:
执行结果
yield value
StateA yield expression return value
Traceback (most recent call last):
File "yield-sample.py", line 9, in <module>
print generator.send("yield expression return value")
StopIteration
下面的代码是不是也是可以的?
其实没啥, 就是去掉了 print generator.send(None)
执行结果
Traceback (most recent call last):
File "yield-sample.py", line 8, in <module>
&
7fe0
nbsp; print generator.send("yield expression return value")
TypeError: can't send non-None value to a just-started generator
这是为什么? 这要追述一下generator.send(value)的作用: 给yield表达式传值, 也就是说让(yield expression) = value, (注意: 是刚刚挂起的yield); 为了达到这个目的, 在此之前一定要让generator挂起一次才行, 所以在此之前必须有generator.next()/send(None) 的调用。
相同点
generator.send(None) 和generator.next() 作用是相同的。 都是驱使生成器从一个yield向下一个yield去执行函数体, 然后挂起返回yield后面的表达式。
不同点
1. generator.send(value) 要在generator.next()/send(None)之后执行, 他的作用: 返回当前挂起yield expression = value, 如果让当前的yield挂起, 必须执行一次next()/send(None)。
2. 其实最大的不同就是, send可以把函数外的value能传到到函数中, 而next不能。
背景介绍
最近在学习Tornado的async编程技巧, 发现yield是基础, 为了弥补之前对他的疏忽, 特此发文深入加深其印象, 以及提高其作用。基础概念
yield的作用就是挂起程序, 并且返回yield之后的值。 举个很简单的例子:[code=language-python] #-*- coding: utf-8 -*- def gen(): b = yield "yield value" print "StateA ", b generator = gen() print generator.next()
对上述程序进行简单的分析:
执行输出的结果:yield value,
generator = gen() , 创建一个生成器, (含有yield的函数体, 其函数调用的结果就是生成一个生成器, 不会执行其函数体。)
generator.next(), 只有当生成器的next函数被第一次触发, 函数体才会被执行, 到第一个yield处挂起。程序稍作修改来验证一下:
[code=language-python]#-*- coding: utf-8 -*- def gen(): print "enter gen()" b = (yield "yield value")#pause print "StateA ", b generator = gen() print "created a generator" print generator.next()
执行结果:
created a generator
enter gen()
yield value
如果生成器的next函数被第二次触发(再次例子中), 由于没有yield了, 会在函数体执行结束之后抛出异常。
[code=language-python]#-*- coding: utf-8 -*- def gen(): b = (yield "yield value")#pause print "StateA ", b generator = gen() print generator.next() print generator.next()
执行结果:
yield value
StateA None
Traceback (most recent call last):
File "yield-sample.py", line 9, in <module>
print generator.next()
StopIteration
b = (yield "yield value") , 从上述的执行结果中看, b的值为None, 同时应该注意到, 复制动作是在第二次next的时候被调用到的。
我们再想, 如何让yield expression有返回值, 并且此返回值是从外围穿入进去的, 这正是generator.send(value)要做的事情:
[code=language-python]#-*- coding: utf-8 -*- def gen(): b = (yield "yield value")#pause print "StateA ", b generator = gen() print generator.next() print generator.send("yield expression return value")
执行结果
yield value
StateA yield expression return value
Traceback (most recent call last):
File "yield-sample.py", line 9, in <module>
print generator.send("yield expression return value")
StopIteration
下面的代码是不是也是可以的?
[code=language-python]#-*- coding: utf-8 -*- def gen(): b = (yield "yield value")#pause print "StateA ", b generator = gen() print generator.send("yield expression return value")
其实没啥, 就是去掉了 print generator.send(None)
执行结果
Traceback (most recent call last):
File "yield-sample.py", line 8, in <module>
&
7fe0
nbsp; print generator.send("yield expression return value")
TypeError: can't send non-None value to a just-started generator
这是为什么? 这要追述一下generator.send(value)的作用: 给yield表达式传值, 也就是说让(yield expression) = value, (注意: 是刚刚挂起的yield); 为了达到这个目的, 在此之前一定要让generator挂起一次才行, 所以在此之前必须有generator.next()/send(None) 的调用。
总结
带有yield表达式的函数在运行的时候就是一个generator(生成器), 此生成器有两个对外的函数, next()和send(value)相同点
generator.send(None) 和generator.next() 作用是相同的。 都是驱使生成器从一个yield向下一个yield去执行函数体, 然后挂起返回yield后面的表达式。
不同点
1. generator.send(value) 要在generator.next()/send(None)之后执行, 他的作用: 返回当前挂起yield expression = value, 如果让当前的yield挂起, 必须执行一次next()/send(None)。
2. 其实最大的不同就是, send可以把函数外的value能传到到函数中, 而next不能。
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例
- Python 七步捉虫法