您的位置:首页 > 编程语言 > Python开发

关于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.....

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),等以后熟悉了,多看看开源框架,再慢慢体会 ........
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: