python三大神器之生成器
阿新 • • 發佈:2018-11-19
生成器Generator:
本質:迭代器(所以自帶了__iter__方法和__next__方法,不需要我們去實現)
特點:惰性運算,開發者自定義
在python中有三種方法來獲取生成器:
1.通過生成器函式
2.通過各種推導式來實現生成器
3.通過資料的轉換獲取生成器
一個包含yield關鍵字的函式就是一個生成器函式。yield可以為我們從函式中返回值,但是yield又不同於return,return的執行意味著程式的結束,呼叫生成器函式不會得到返回的具體的值,而是得到一個可迭代的物件。每一次獲取這個可迭代物件的值,就能推動函式的執行,獲取新的返回值。直到函式執行結束。
def func(): print('hello') yield 1 print('world') yield 2 g = func() # 呼叫"生成器函式" a = g.__next__() print(a) # a generator(生成器) b = g.__next__() print(b) # yield關鍵字的特點: 可以記錄當前函式中執行的位置,下一次繼續執行 # next和yield是一對搭檔 : next開始函式的執行 yield停止函式的執行
列表推導式的常用寫法:[結果 for 變數 in 可迭代物件]
生成器表示式和列表推導式的語法基本上是一樣的,只是把[ ]替換成( )
倆個的區別:
列表推導式比較耗記憶體,一次性載入.生成器表示式幾乎不佔用記憶體,使用的時候才分配
和使用記憶體
lst = [i for i in range(10)] print(lst) #結果: #[0,1,2,3,4,5,6,7,8,9] g= (i for i in range(10)) print(g) #結果: #<generator object <genexpr> at 0x106768f10>#列印的結果就是一個生成器. 我們可以使用for迴圈來迴圈這個生成器: for i in g: print(i)
send方法:send和__next__一樣都可以讓生成器執行到下一個yield.
def generator(): print(123) content = yield 1 print('=======',content) print(456) yield2 g = generator() ret = g.__next__() print('***',ret) ret = g.send('hello') #send的效果和next一樣 print('***',ret) #send 獲取下一個值的效果和next基本一致 #只是在獲取下一個值的時候,給上一yield的位置傳遞一個數據 #使用send的注意事項 # 第一次使用生成器的時候 是用next獲取下一個值 # 最後一個yield不能接受外部的值
生成器的應用:監聽檔案的輸入,對於檔案中隨時輸入的內容進行自動化展示
import time def tail(filename): f = open(filename) f.seek(0, 2) #從檔案末尾算起 while True: line = f.readline() # 讀取檔案中新的文字行 if not line: time.sleep(0.1) continue yield line tail_g = tail('tmp') for line in tail_g: print(line)