python提供了与next方法调用的代码进行交互的功能。yield将变成一个表达式,而一个值可以通过名为send的新方法来传递。
>>> def psychologist():
... print('Please tell me your problems')
... while True:
... answer = (yield)
... if answer is not None:
... if answer.endswith('?'):
... print("Don't ask yourself")
... elif 'good' in answer:
... print"A that's good, go on"
... elif 'bad' in answer:
... print "Don't be so negative"
...
>>> free = psychologist()
>>> free
<generator object psychologist at 0x02618C88> #生成器
>>> free.next()
Please tell me your problems #第一次调用
>>> free.next() #第二次调用
>>>
>>> free.send('I feel bad') #send接口
Don't be so negative
send的工作机制与next一样,但是yield将变成能够返回传入的值。因而,这个函数可以根据客户端代码来改变其行为。同时,还添加了throw和close啷个函数,以完成该行为。他们将向生成器抛出一个错误。
·throw允许客户端怠慢传入要抛出的任何类型的异常;
·close的工作方式是相同的,但是将会抛出一个特定的异常--CeneratorExit,在这种情况下,生成器函数必须再次抛出GeneratorExit或StopIteration异常。
因此一个典型的生成器模板应该类似于如下所示。
>>> def my_generator():
... try:
... yield 'something'
... except ValueError:
... yield 'dealing with the exception
... finally:
... print "OK let's clean"
...
>>> gen = my_generator()
>>> gen.next()
'something'
>>> gen.throw(ValueError('mean mean mean'))
'dealing with the exception'
>>> gen.close()
OK let's clean
>>>
>>> gen.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
finally捕获任何违背捕获的close和throw调用,是完成清理工作的推荐方式。GeneratorExit异常在生成器中是无法捕获的,因为他被编译器用来确定调用close是否正常退出。如果有代码与这个异常失恋,那么解释程序将跑出一个系统错误并且退出