生成器函式以及生產消費模型
阿新 • • 發佈:2018-12-26
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> 首次執行時不會執行任何操作,只是變成可迭代物件而已
11print(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 deftest_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()