1. 程式人生 > >生成器函式以及生產消費模型

生成器函式以及生產消費模型

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()