關於Python中的yield

在介紹yield前有必要先說明下Python中的迭代器(iterator)和生成器(constructor)。python

1、迭代器(iterator)函數

在Python中,for循環能夠用於Python中的任何類型,包括列表、元祖等等,實際上,for循環可用於任何「可迭代對象」,這其實就是迭代器工具

迭代器是一個實現了迭代器協議的對象,Python中的迭代器協議就是有next方法的對象會前進到下一結果,而在一系列結果的末尾是,則會引起StopIteration。任何這類的對象在Python中均可以用for循環或其餘遍歷工具迭代,迭代工具內部會在每次迭代時調用next方法,而且捕捉StopIteration異常來肯定什麼時候離開。spa

使用迭代器一個顯而易見的好處就是:每次只從對象中讀取一條數據,不會形成內存的過大開銷。code

好比要逐行讀取一個文件的內容,利用readlines()方法,咱們能夠這麼寫:orm

1
2
 line  .:
     line

這樣雖然能夠工做,但不是最好的方法。由於他其實是把文件一次加載到內存中,而後逐行打印。當文件很大時,這個方法的內存開銷就很大了。對象

利用file的迭代器,咱們能夠這樣寫:接口

1
2
 line  :   
     line

這是最簡單也是運行速度最快的寫法,他並沒顯式的讀取文件,而是利用迭代器每次讀取下一行。內存

2、生成器(constructor)ci

生成器函數在Python中與迭代器協議的概念聯繫在一塊兒。簡而言之,包含yield語句的函數會被特意編譯成生成器。當函數被調用時,他們返回一個生成器對象,這個對象支持迭代器接口。函數也許會有個return語句,但它的做用是用來yield產生值的。

不像通常的函數會生成值後退出,生成器函數在生成值後會自動掛起並暫停他們的執行和狀態,他的本地變量將保存狀態信息,這些信息在函數恢復時將再度有效

1
2
3
4
5
6
7
8
  gn:
...      i  n:
...              i 
...
  i  g:
...      i,,
...
 :  :  :  :  :

要了解他的運行原理,咱們來用next方法看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 t = g
 t.

 t.

 t.

 t.

 t.

 t.
Traceback most recent call last:
  File , line ,  module

在運行完5次next以後,生成器拋出了一個StopIteration異常,迭代終止。
再來看一個yield的例子,用生成器生成一個Fibonacci數列:

1
2
3
4
5
6
7
8
9
10
 fab:
    a,b = ,
     a  :
         a
        a, b = b, a+b
 
  i  fab:
...      i,,
...
 ,  ,  ,  ,  ,  ,  ,  ,

看到這裏應該就能理解生成器那個很抽象的概念了吧~~

相關文章
相關標籤/搜索