generator本身也是iterator,和iterator不同的地方在於generator會透過function宣告的方式,但有別於一般的function直接return回傳值,generator的function會在”有需要”的時候,使用yield來回傳值。為什麼稱為”有需要”的時候呢?因為generator在每次呼叫next()回傳值後,會記下所有的資料並保留最後一次執行狀態,直到下一次呼叫next()才會再繼續執行未結束的狀態。我們可以看一下下面這個範例:
1 | def transform(data): |
在每一次呼叫next()時,generator才會開始執行,並且每次執行到yield回傳值後停止,並保留執行狀態直到下一次呼叫next()才繼續執行。當generator終止後呼叫next()則會發生StopIteration。
1 | 'python') char = transform( |
也可以使用for loop來呼叫generator
1 | for char in transform('python'): |
使用generator最大的好處在於可以有效的處理一次性使用大量使用Memory的情況,將要一次性處理的過程拆成generator分次執行。例如當需要讀取很大的檔案處理時(甚至是多個很大的檔案)。而且使用generator可以降低iterator在loop的維度,讓程式碼可以更加的乾淨。
1 | def get_line_title(file_name): |
上面的範例會產生generator並逐次判斷每一行內容,並回傳所有的標題。其中會用到兩個for loop和一個邏輯判斷,我們可以改寫成下面這樣,把讀取的部份和邏輯判斷的部份拆開來。
1 | def get_line(files): |
如果善用generator可以有效的管理Memory的使用,也可以讓程式碼更加的有可讀性!
參考資料:
Python Docs - Generators
Iterators & Generators
Introduction to Python Generators