- 从句法上讲,生成器是一个带yield语句的函数,yield语句能暂停执行并返回一个中间结果,当next()方法被调用时,它会从离开地方继续执行.当到达真正的返回或者函数结束没有更多的值返回时(当调用next()),会抛出StopIteration异常,可用于for循环(有next()调用和对StopIteration的处理).
- 可以类似序列的迭代器接口,通过next()返回下一个元素
- 函数生成器的另一个方面更加强力...协同程序的概念,协同程序是可以运行的独立函数调用,可以暂停或者挂起,并从程序离开的地方继续或者重新开始,调用者和(被调用的)协同程序可以通信.
- 使用生成器循环处理一块数据时,可以只在需要时调用next(),这就避免了一个很长的for循环.
- python 2.5后,生成器有send()以及close()接口.
下面以一个例子来说明生成器的调用执行过程,以及通过send(),close()接口与生成器进行通讯。
>>> def counter(start_at = 0):
count = start_at
while True:
val = (yield count) #1 返回count当前值,并暂停执行直到下次调用next()或send()
print 'yield count = ', count #2 输出count的当前值
print 'yield val = ', val #3 输出接受到的通过接口send()发送的值,调用next()时为None
if val is not None: #4 如已调用send()接口,则处理接收到的值
print 'val = ', val
print 'count = ', count
count = val
else:
count += 1 #5 count加1,重新回到#1处执行
>>> count = counter(10)
>>> count.next()
10 #1 从#1处第一次返回count的初始值
>>> count.next() #1 继续从#1处接着往下执行
yield count = 10 #2 输出count当前值
yield val = None #3 没有send()调用
11 #5#1 #5处已更新count的值,并在#1处返回
>>> count.send(20) #1 我们调用send()发送数据20,程序从#1处继续运行,但接受到send值20
yield count = 11
yield val = 20 # 接受到20的值
val = 20
count = 11
20
>>> count.next()
yield count = 20
yield val = None
21
>>> count.close() # 关闭迭代器,迭代器结束
>>> count.next() # 迭代器已结束,产生StopIneration异常
Traceback (most recent call last):
File "<pyshell#299>", line 1, in <module>
count.next()
StopIteration
>>>