Python中的yield用法

  在Python中,我們將帶有 yield 的函數稱之爲 generator(生成器)。generator可以一邊循環一邊計算,是可迭代對象,也就是說可以使用for循環來迭代出generator的各個值。

一、

  一般爲了說明generator,都會使用斐波那契數列來舉例,這裏也不例外:

def fab(max): 
    n, a, b = 0, 0, 1 
    L = [] 
    while n < max: 
        yield b 
        a, b = b, a + b 
        n = n + 1 

generator測試

  如結果所示,調用 fab(5) 並不會執行 fab 函數,而是返回一個 可迭代對象, 每次循環都會執行 fab 函數內部的代碼,執行到 yield b 時,fab 函數就返回一個迭代值,下次迭代時,代碼從 yield b 的下一條語句繼續執行,而函數的本地變量看起來和上次中斷執行前是完全一樣的,函數繼續執行,直到再次遇到 yield或return。
  在一個 generator中,如果沒有 return,則默認執行至函數完畢,如果在執行過程中遇見了return,則直接拋出 StopIteration 終止迭代。

二、

  與generator有關的很重要的函數有next()和send(parameter)。
因爲generator是可迭代對象,我們可以使用next()來手動迭代其各個值。仍然拿上面fab()函數來舉例,如下圖所示:

  send(parameter)函數可以給yield表達式傳值,而next()只能傳遞None進去。因此,某種程度上c.next() 和 c.send(None)的作用是一樣的。來看例子:
  
  可以看到,認爲n=5、m=10是錯誤的!這是因爲yield是一個表達式,(yield 5)本身是有一個返回值的,這個返回值可以由send(parameter)函數傳遞進去:
  
  需要注意的是,第一次調用時不能使用send發送一個非None值,否則會報錯,因爲沒有yield語句來接收這個值。可以使用next()語句或send(None)。
  send(parameter) 和 next()這兩個函數是有其自己的返回值的,它們的返回值很特殊,返回的是下一個yield表達式的參數。比如yield 5,則返回5。
  
  因爲for循環迭代generator時,其實是一次次調用了next()函數,直到拋出StopIteration異常爲止。而每次迭代出的值,其實就是next()函數的返回值,也就是yield表達式的參數!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章