关于Python生成器(Generator的yield、next、send)
2015-10-10 01:24
681 查看
习惯了C++和Java等强类型的语言,函数调用都是顺序执行的,返回之后栈清空,不留痕迹。初次遇到Python生成器,理解起来,真是破费周章。
关于Python生成器,大概需要关心的主要是yield关键字,以及其后的next和send函数的调用。next函数在迭代的时候,为隐式调用(implicit)。
一:生成器函数
生成器函数和一般函数外观上没有什么不同。主要是一般函数通过return结束调用,交出执行时序,而生成器函数使用yield。
一般函数return后,会清除栈空间(C/C++,python的实现暂不清楚),而yield则会保留当前的执行状态,下次调用next的时候,继续执行。
因此生成器的yield,只是临时且主动的交出控制权(temporary、volunteer),下次next还会从yield之后取得控制权。
一般函数调用后,会马上执行,而生成期函数调用之后不会马上执行,更像是一个生成器对象的调用
二:yield关键字、next、send
含有yield关键字的函数为生成器函数。通过调用生成器函数获得生成器。通过生成器调用next和send触发生成器运行到下一个yield语句,yield保存当前的运行状态,并且返回后面的操作数。send不光会返回操作数,而且会将send的参数作为yield的返回值。
三:生成器完成
当next或者send调用使得生成器函数执行完成(循环执行完了),再次调用,会抛出StopIteration异常。内置的for迭代应该是捕获了该异常,判断迭代完成
Talk is cheap, show me the code.....
执行结果:
generator()9
9
(111, 10)
generator()10
10
(111, 11)
generator()11
11
[Finished in 0.1s]
执行结果:
generator()9
9
(111, 21)
generator()21
21
Traceback (most recent call last):
File "/Users/alex/Desktop/myProgram/python/test.py", line 126, in <module>
print z.next() #error
File "/Users/alex/Desktop/myProgram/python/test.py", line 118, in prt2
num+=1
TypeError: unsupported operand type(s) for +=: 'NoneType' and 'int'
[Finished in 0.1s with exit code 1]
执行结果:
9
Traceback (most recent call last):
File "/Users/alex/Desktop/myProgram/python/test.py", line 135, in <module>
print z.next() #error,生成器已经结束了,没有next值可以调用了
StopIteration
总结:传说生成器非常强大,但是初次使用,感觉就像一个能够保存执行中间过程的函数,通过next和send往后迭代,直到生成器函数执行完成。
至于有神马用(luan)处(yong),等以后熟悉了,多看看开源框架,再慢慢体会 ........
关于Python生成器,大概需要关心的主要是yield关键字,以及其后的next和send函数的调用。next函数在迭代的时候,为隐式调用(implicit)。
一:生成器函数
生成器函数和一般函数外观上没有什么不同。主要是一般函数通过return结束调用,交出执行时序,而生成器函数使用yield。
一般函数return后,会清除栈空间(C/C++,python的实现暂不清楚),而yield则会保留当前的执行状态,下次调用next的时候,继续执行。
因此生成器的yield,只是临时且主动的交出控制权(temporary、volunteer),下次next还会从yield之后取得控制权。
一般函数调用后,会马上执行,而生成期函数调用之后不会马上执行,更像是一个生成器对象的调用
二:yield关键字、next、send
含有yield关键字的函数为生成器函数。通过调用生成器函数获得生成器。通过生成器调用next和send触发生成器运行到下一个yield语句,yield保存当前的运行状态,并且返回后面的操作数。send不光会返回操作数,而且会将send的参数作为yield的返回值。
三:生成器完成
当next或者send调用使得生成器函数执行完成(循环执行完了),再次调用,会抛出StopIteration异常。内置的for迭代应该是捕获了该异常,判断迭代完成
Talk is cheap, show me the code.....
def prt1(num): while True: print "generator()"+str(num) yield num num+=1 print (111,num) z=prt1(9) #此处不会导致prt1函数真正执行,因此第一个print语句不会执行 print z.send(None) #生成器函数开始执行,打印第二个print,到yield处,返回9 print z.send(1) #生成器函数从上次yiled之后继续执行,返回10, #由于yile的返回值没有任何赋值,这里的参数1并没有什么用(luan)处(yong) print z.next() #next在这种情况下等同于send(xxx)
执行结果:
generator()9
9
(111, 10)
generator()10
10
(111, 11)
generator()11
11
[Finished in 0.1s]
def prt2(num): while True: print "generator()"+str(num) num=yield num num+=1 print (111,num) z=prt2(9) #此处不会导致prt1函数真正执行,因此第一个print语句不会执行 print z.next() #生成器函数开始执行,打印第一个print,到yield处,返回9 print z.send(20) #执行到上次yield,首先赋值给num=20,然后往下执行,打印,然后 yiled返回21 print z.next() #error,执行到上次yiled之后,由于是next调用,给num赋值为None,然后num+=1,抛出异常
执行结果:
generator()9
9
(111, 21)
generator()21
21
Traceback (most recent call last):
File "/Users/alex/Desktop/myProgram/python/test.py", line 126, in <module>
print z.next() #error
File "/Users/alex/Desktop/myProgram/python/test.py", line 118, in prt2
num+=1
TypeError: unsupported operand type(s) for +=: 'NoneType' and 'int'
[Finished in 0.1s with exit code 1]
z=prt3(9) print z.next() #OK,返回9,生成器函数执行结束了 print z.next() #error,生成器已经结束了,没有next值可以调用了,抛出StopIteration异常
执行结果:
9
Traceback (most recent call last):
File "/Users/alex/Desktop/myProgram/python/test.py", line 135, in <module>
print z.next() #error,生成器已经结束了,没有next值可以调用了
StopIteration
总结:传说生成器非常强大,但是初次使用,感觉就像一个能够保存执行中间过程的函数,通过next和send往后迭代,直到生成器函数执行完成。
至于有神马用(luan)处(yong),等以后熟悉了,多看看开源框架,再慢慢体会 ........
相关文章推荐
- leetcode之First Bad Version
- web服务监控邮件告警python程序
- python中else语句的用法
- LintCode -- 不同的二叉查找树(python-O(n)时间复杂度)
- 2015/10/9 Python核编初级部分学习总结
- 下载python的各种扩展库
- Python学习笔记
- [每日一答] [20151009] 一键式安装Python数据分析工具Canopy
- python按日期分类备份文件夹
- 【python问题系列--4】ValueError: operands could not be broadcast together with shapes (100,3) (3,1)
- 2015/10/9 Python基础(21):可调用和可执行对象
- Python抓取糗事百科
- 萤火虫算法-python实现
- 进化策略-python实现
- python2和python3中的编码问题
- python编码问题.
- Python学习笔记<函数式编程>
- python几个内建函数
- Python学习之正则表达式
- Improve Your Python: 'yield' and Generators Explained