生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果。
生成器的使用:
def Zrange(n):
i=0
while i<n:
yield i
i+=1
if __name__=="__main__":
zrange=Zrange(3)
print zrange
print [i for i in zrange]
结果为:
generator object Zrange at 0x0000000002BF6360
[0, 1, 2]
在这个例子中,定义了一个生成器函数,函数返回一个生成器对象,最后通过for语句进行迭代访问。
生成器的执行流程
def Zrange(n):
print "beginning of Zrange"
i=0
while i<n:
print "before yield!",i
yield i
i+=1
print "after yield",i
print "endding of Zrange"
if __name__=="__main__":
zrange=Zrange(3)
print zrange.next()
print zrange.next()
print zrange.next()
print zrange.next()
结果为:
beginning of Zrange
before yield! 0
0
after yield 1
before yield! 1
1
after yield 2
before yield! 2
2
after yield 3
endding of Zrange
Traceback (most recent call last):
File “C:/Users/Administrator/Desktop/zr2.py”, line 15, in
print zrange.next()
StopIteration
通过结果可以看到:
当调用生成器函数的时候,函数只是返回了一个生成器对象,并没有执行。
当next()方法第一次被调用的时候,生成器函数才开始执行,执行到yield语句处停止
next()方法的返回值就是yield语句处的参数(yielded value)
当继续调用next()方法的时候,函数将接着上一次停止的yield语句处继续执行,并到下一个yield处停止;如果后面没有yield就抛出StopIteration异常。
生成器的send()和close()方法
send(value):
从前面了解到,next()方法可以恢复生成器状态并继续执行,其实send()是除next()外另一个恢复生成器的方法。Python 2.5中,yield语句变成了yield表达式,也就是说yield可以有一个值,而这个值就是send()方法的参数,所以send(None)和next()是等效的。同样,next()和send()的返回值都是yield语句处的参数(yielded value)。关于send()方法需要注意的是:调用send传入非None值前,生成器必须处于挂起状态,否则将抛出异常。也就是说,第一次调用时,要使用next()语句或send(None),因为没有yield语句来接收这个值。
close():
这个方法用于关闭生成器,对关闭的生成器后再次调用next或send将抛出StopIteration异常。
def Zrange(n):
i=0
while i<n:
val=yield i
print "val is: ",val
i+=1
if __name__=="__main__":
zrange=Zrange(5)
print zrange.next()
print zrange.next()
print zrange.send("Hello")
zrange.close()
print zrange.send("world")
结果为:
0
val is: None
1
val is: Hello
2
Traceback (most recent call last):
File “C:/Users/Administrator/Desktop/zr4.py”, line 14, in
print zrange.send(“world”)
StopIteration