生成器接受和返还功能在执行过程中的详解以及生成器实现协同
1 import random 2 3 SENTENCES=[ 4 'How are you ?', 5 'Fine,thank you!', 6 'Nothing much', 7 'Just chilin' 8 ] 9 10 def random_conversation(): 11 recv=yield 'Hi' 12 print('************',recv) 13 print('a') 14 while recv!='Bye': 15 print('b') 16 recv=yield random.choice(SENTENCES) 17 print('--------------',recv) 18 19 g=random_conversation() 20 21 print('~~~~~~~~~~~~~',g.send(None)) 22 23 while True: 24 try: 25 print('c') 26 reply=g.send(input()) 27 except StopIteration: 28 break 29 print('>>>'+reply) 30 print('Conversation Over!')
yield具有接受和返还值两种功能,在上面的程序中,yield可以接受来自g.send(input())的数据,并将接受得到的数据赋值给recv,同时yield也会返回yield后的数据,例如上程序中recv=yield 'Hi' 中返还Hi,类似return的功能。
程序执行过程中,遇到含有yield的语句可以看做从右往左执行,即先yield 'value' 返回value值,挂起等待,等到下一次接受 来自g.send(input())数据 赋值给recv。接受完数据继续运行程序直到再次遇到yield 'Value' 返还数据,挂起等待,例如上面11行接收完数据之后继续运行到第16行
yield random.choice(SENTENCES)
返还数据random.choice(SENTENCES)后,在16行处recv=yield等待接受数据挂起等待
执行结果过如下
1 ~~~~~~~~~~~~~ Hi #为触发生成器,第一次必须发送None (记住)
2 c #yield返还Hi后23行while循环开始执行,而此时生成器函数在recv=yield处挂起等待下一次接收发送来的数据
3 xiongxueqi #26行键盘输入数据xiongxueqi
4 ************ xiongxueqi #生成器函数从上次挂起的地方继续,recv=yield 接收发送来的数据xiongxueqi 并通过第12行输出
5 a
6 b #执行到第15行,运行到16行返还数据random.choice(SENTENCES)后,在16行处recv=yield等待接受数据挂起等待
7 >>>How are you ? #返还执行第29行程序
8 c #迭代未完成继续while循环执行第25行程序
9 fanbinbin #第26行输入数据fanbinbin,16行处recv=yield等待结束,接受数据赋值recv继续执行
10 -------------- fanbinbin #顺序执行第17行代码
11 b #接受到的值不等于Bye 继续14行的while循环
12 >>>Just chilin #再次来到16行yield random.choice(SENTENCES)返还数据给26行reply 并接下来输出
13 c #迭代未结束,继续while循环
14 Bye #26行键盘输入Bye
15 -------------- Bye #16行处recv=yield等待结束,接受数据赋值recv继续执行,此时recv=Bye,17行输出recv值
16 Conversation Over! #14行recv==Bye 循环结束,迭代结束,27行接收到StopIteration异常,23行while循环结束,执行30行语句
利用生成器实现协同程序(Coroutines)模拟并行
1.speaker()函数用于返回随机SENTENCES
2.replier()函数接收来自speaker的SENTENCES并随机回答
1 import random 2 3 SENTENCES=[ 4 'How are you ?', 5 'Fine,thank you!', 6 'Nothing much', 7 'Just chilin', 8 'Bye!' 9 ] 10 11 def speaker(): 12 while True: 13 yield random.choice(SENTENCES) 14 15 def replier(): 16 while True: 17 recv=yield 18 print('Received:%s'%recv) 19 if recv=='Bye!': 20 break 21 print('Replied:%s'%random.choice(SENTENCES)) 22 23 s=speaker() 24 r=replier() 25 r.send(None) 26 while True: 27 recv=s.send(None) 28 try: 29 a=r.send(recv) 30 except StopIteration: 31 break 32 print('Conversation ends!')
运行结果如下
1 Received:Nothing much 2 Replied:Just chilin 3 Received:Just chilin 4 Replied:Fine,thank you! 5 Received:How are you ? 6 Replied:Fine,thank you! 7 Received:Bye! 8 Conversation ends!
每次运行结果都不一定相同
1 Received:Just chilin 2 Replied:Bye! 3 Received:How are you ? 4 Replied:Just chilin 5 Received:Just chilin 6 Replied:Just chilin 7 Received:How are you ? 8 Replied:Fine,thank you! 9 Received:Nothing much 10 Replied:Just chilin 11 Received:Just chilin 12 Replied:Just chilin 13 Received:Bye! 14 Conversation ends!