生成器函數是使用yield關鍵字的函數,能暫停執行并逐步產出值。它與普通函數不同,調用時返回生成器對象而非立即執行,適合處理大數據、惰性求值等場景。1. yield產出值并保留狀態,等待下次調用繼續執行;2. 生成器節省內存,適合處理大文件或無限序列;3. yield可用于簡化流程控制;4. yield只能在函數體內使用,且生成器不可重置;5. 雖節省內存但頻繁調用可能影響性能。掌握yield可有效應對流式數據和惰性計算需求。
在python中,yield關鍵字是生成器函數的核心。它不像普通函數那樣直接返回一個值然后結束,而是“產出”一個值,并暫停函數的執行狀態,等待下一次被調用時繼續執行。這使得生成器非常適合處理大數據集、惰性求值等場景。
什么是生成器函數?
生成器函數和普通函數看起來差不多,區別在于它使用 yield 而不是 return。當你調用一個生成器函數時,它不會立即執行函數體,而是返回一個生成器對象。這個對象可以逐步迭代,每次調用 .next() 或者用 for 循環時,函數會從上次 yield 的位置繼續執行。
舉個簡單例子:
def count_up_to(max): count = 1 while count <= max: yield count count += 1 counter = count_up_to(5)
這時,counter是一個生成器對象。你每調用一次 next(counter),它就會輸出一個數字,直到結束。
立即學習“Python免費學習筆記(深入)”;
yield的典型使用場景
處理大量數據時節省內存
如果你要處理非常大的數據集,比如讀取一個幾GB的日志文件,一次性加載到內存顯然不現實。這時候可以用生成器一行一行地讀取:
def read_large_file(file_path): with open(file_path, 'r') as f: for line in f: yield line.strip()
這樣每次只讀取一行,處理完再讀下一行,大大減少內存占用。
實現無限序列
有時候你需要一個無限增長的序列,比如斐波那契數列。生成器可以輕松實現這一點:
def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b
你可以隨時取前幾個數,也可以結合條件中斷循環,非常靈活。
簡化異步或流程控制
雖然現在有 async/await,但在早期Python代碼中,生成器常用來模擬協程行為。通過 yield 控制執行流程,在某些復雜的任務調度中有其獨特優勢。
yield和return的區別
- return:直接返回一個值,函數終止。
- yield:返回一個值,但保留函數當前的狀態,下次調用時繼續執行。
比如下面這個函數:
def demo(): yield 1 yield 2 yield 3
調用時:
gen = demo() print(next(gen)) # 輸出1 print(next(gen)) # 輸出2
函數會在每個 yield 暫停,而不是一次性執行完。
使用yield時需要注意的地方
- 不能隨便放在任何地方:yield只能出現在函數體內,不能寫在類定義、全局作用域或其他語句塊中。
- 生成器是一次性的:一旦遍歷完成,就不能重置。如果需要重新開始,必須重新創建生成器對象。
- 性能并不總是最優:雖然節省內存,但如果頻繁調用生成器,可能會比列表推導式慢一些。
基本上就這些。掌握好yield,你就掌握了Python中處理惰性計算和流式數據的關鍵工具。