python学习,day4:生成器,通过yield实现单线程情况下的并发运算

首先了解一个斐波那契函数的实现,了解下生成器的工作流程

 1 # coding=utf-8
 2 # Author: RyAn Bi
 3 def fib(max):
 4     n,a,b=0,0,1
 5     while n < max:
 6         #print(b)
 7         yield b   #定义一个生成器,也是个断点,每次运行都会再此调用
 8         a,b = b,b+a
 9         n = n +1
10     return 'done'
11 f=fib(2)                             
12 while True:
13     try:                              #定义一个异常处理
14         x= next(f)                     #运行下一步
15         print('f:',x)
16     except StopIteration as e:                 #处理异常,当运行到return的时候会进行下一步
17         print('Generator return value:',e.value)
18         break

其中,了yield关键字的核心用法,即逐个生成。在这里获取了两个生成器产生的值,即0和1。分别由next函数和send()函数获得

第一次调用__next__函数的时候,我们从生成器函数的起点开始,然后在yield处结束,需要注意的是,赋值语句不会调用,此处yield i和含义和return差不多。
但是第二次调用__next__函数的时候,就会直接从上一个yield的结束处开始,也就是先执行赋值语句,然后输出字符串,进入下一个循环,直到下一个yield或者生成器结束
再次看初始的那段代码,可以发现第二次调用的时候没有选择使用__next__函数,而是使用了一个sent()函数。这里就需要注意,sent()函数的用法和__next__函数不太一样。sent()函数只能从yield之后开始,到下一个yield结束。这也就意味着第一次调用必须使用__next__函数。

看下面的例子

 1 def consumer(name):
 2     print('%s要吃包子了'%name)
 3     while True:
 4         baozi =yield
 5         print('包子%s来了,要被%s吃了!'%(baozi,name))
 6 
 7 c =consumer('bb')
 8 c.__next__()
 9 c.send('韭菜馅')
10 c.__next__()


用send给包子赋值

 1 # coding=utf-8
 2 # Author: RyAn Bi
 3 import time
 4 
 5 def consumer(name):
 6     print('%s要吃包子了'%name)
 7     while True:
 8         baozi =yield
 9         print('包子%s来了,要被%s吃了!'%(baozi,name))
10 
11 # c =consumer('bb')
12 # c.__next__()
13 # c.send('韭菜馅')
14 # c.__next__()
15 
16 def producer(name):       #制造包子
17     c = consumer('A')
18     c1 = consumer('B')      #c和c1达到并行的效果,利用生成器
19     c.__next__()
20     c1.__next__()
21     print('a老子要吃包子了')
22     for i in range(10):
23         time.sleep(1)
24         print('做了2个包子')
25         c.send(i)
26         c1.send(i)
27 producer('bb')

 

posted @ 2019-03-01 09:38  bbgoal  阅读(328)  评论(0编辑  收藏  举报