生成器函数以及生产消费模型

1.生成器函数,即最终的输出用yield替代return,其他形式不变的函数,而且相比于return,输入yield函数不会立即停止

 1 def test():
 2     print('你好')
 3     return 10
 4 def test_1():
 5     print('你好')
 6     yield 10
 7 a = test()
 8 print(a)
 9 b = test_1()
10 print(b)    #<generator object test_1 at 0x00000000024F3570> 首次运行时不会执行任何操作,只是变成可迭代对象而已 
11
print(b.__next__()) #只有在对其执行next函数操作时才会有打印值 你好 10

2.生成器函数每次执行到yield都会保留函数状态,让函数执行的光标停在当前位置

def test():
    yield 1
    yield 2
    yield 3
a = test()
print(a)   #<generator object test at 0x00000000024C3138>
print(a.__next__())   #1
print(a.__next__())   #2
print(a.__next__())   #3
print(a.__next__())   #直接报错,因为yield后面的输出只能取一次,取完在取则报错

3.相对于return,yield会保留函数当前状态,只有在调用的时候才会执行,而且一次一次的执行,不会因为一次执行全部操作而占据太大的内存导致卡机等(比如下面的代码如果100变成很大很大的数字,第一种执行方法一定会卡)

 1 def test():
 2     ret = []
 3     for i in range(100):
 4         ret.append('people%s' %i)
 5     print(ret)
 6 test()    #直接打印所有的people
 7 def test_1():
 8     for i in range(100):
 9         yield i
10 a = test_1()
11 for a1 in a:
12     print(a1)    #相比于return一次占据所有打印出people的内存,这种一个个的取显然更省内存

4.列表解析与生成器表达式:下面的代码与上面的代码意义相同,提供了一种简便表示列表的方法与生成器表达式的表示方法

a = ['people%s' %i  for i in range(100)]
print(a)
b = ('people%s' %i for i in range(100))
print(list(b))

5.send(a):重要函数,一般与yield一起操作(在yield之后输入),会将a替代yield的返回值被变量接受

def test():
    file = yield 0
    print(file)
    yield None
a = test()
print(a.__next__())
a.send('aini')

 6.生产消费者模型:同时运行以下两个函数,相当于只运行一个函数(两个函数互相衔接),比其他方法更省内存(重要)

 1 import time
 2 def buy(name):
 3     print('卖辣条啦!')
 4     time.sleep(2)
 5     while True:
 6         latiao = yield
 7         time.sleep(1)
 8         print('%s吃了第%s包辣条' %(name,latiao))
 9 
10 def sell():
11     s1 = buy('aaa')
12     s1.__next__()
13     for i in range(1,11):
14         s1.send(i)
15     time.sleep(3)
16     print('诶呀卧槽,aaa撑死啦!')
17 sell()

 

posted @ 2018-12-26 21:38  机智的小哥哥  阅读(244)  评论(0编辑  收藏  举报