国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

從python的yield說起

2019-11-14 17:34:31
字體:
來源:轉載
供稿:網友

前段時間在讀trac 中wiki模塊的源碼的時候,發現了很多地方都使用了yiled這一關鍵詞,

感覺是在需要返回某個值的地方通過yield來代替return,

不是很明白其用法,所以仔細研究下。

 

一個使用了yiled關鍵字的函數就不再是一個普通的函數了,而是一個生成器函數(generator function),

當函數被調用的時候將返回一個迭代器(iterator)。

 

所以下面將分別講解迭代器和生成器這兩個概念。

 

一. 迭代器(Iterator)

 

 寫道
迭代器是一個對象,它實現了迭代器協議,
一般需要實現如下兩個方法
1)next方法
返回容器的下一個元素
2)__iter__方法
返回迭代器自身

 

 

對于for語言大家可能都不陌生,我們很多時候需要對一些容器對象進行遍歷就會使用到for循環:

 

Python代碼  收藏代碼
  1. l=[0,1,2,3,4,5,6]  
  2. for i in l:  
  3.     PRint i  

 

l是一個type為list的對象,這段for-in代碼在運行的時候其實是調用了l的__iter__()函數,返回了一個實現了__next__()或next()(各個版本的python可能不一樣,我試驗的時候所使用的版本為2.6.2)的迭代器對象,每循環一次就會通過next取下一個元素。

 

當然我們完全沒有必要先把所有的元素都算出來放到一個list里或者其他容器類里進行循環,這樣比較浪費空間。

我們可以直接創建自己的一個迭代器。

 

Python代碼  收藏代碼
  1. # -*- coding: utf-8 -*-  
  2.   
  3. '''''Fibonacci iterator'''  
  4.   
  5. class Fib:  
  6.     '''''一個可以生成Fibonacci 數列的迭代器'''  
  7.   
  8.     def __init__(self, max):  
  9.         self.max = max  
  10.   
  11.     def __iter__(self):  
  12.         self.a = 0  
  13.         self.b = 1  
  14.         return self  
  15.   
  16.     def next(self):  
  17.         fib = self.a  
  18.         if fib > self.max:  
  19.             raise StopIteration  
  20.         self.a, self.b = self.b, self.a + self.b  
  21.         return fib  

 

 

定義好了這個Fibonacci迭代器,我們就可以來使用它了。

 

 

Python代碼  收藏代碼
  1. from fibonacci2 import Fib  
  2. for n in Fib(1000):  
  3.     print n  

 

當調用Fib(1000)的時候,將生成一個迭代器對象,每一次循環都將調用一次next取到下一個值。

所以我們可以看出迭代器有一個很核心的東西就是在循環中,迭代器可以記住之前的狀態。

 

 

二.生成器

 

前面我們說了,任何使用了yield關鍵字的函數都不再是普通的函數了,我們還是來看實例吧,這樣比較容易理解

 

 

Python代碼  收藏代碼
  1. def fib(max):  
  2.     a, b = 0, 1            
  3.     while a < max:  
  4.         yield a            
  5.         a, b = b, a + b    

   這里簡單的幾行代碼就實現了上面的迭代器類那么一大堆代碼所實現的功能

 

   使用的時候和上面很類似:

 

 

Python代碼  收藏代碼
  1. from fibonacci import fib  
  2. for n in fib(1000):  
  3.     print n  

 

引文fib函數使用了yield所以它是一個生成器函數,當我們調用fib(1000)的時候它其實是返回了一個迭代器,且這個迭代器可以控制生成器函數的運行。

我們通過這個返回的迭代器的動作控制fib這個生成器函數的運行。

每當調用一次迭代器的next函數,生成器函數運行到yield之處,返回yield后面的值且在這個地方暫停,所有的狀態都會被保持住,直到下次next函數被調用,或者碰到異常循環退出。

 

所以生成器的概念還是很簡單的。

 

三.總結

 

1.for-in語句在底層都是對一個迭代器對象進行操作的

2.使用了yield關鍵字的函數就是一個生成器函數,被調用的時候生成一個可以控制自己運行的迭代器。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 汾西县| 桐乡市| 福建省| 阜新市| 广水市| 永定县| 买车| 桓台县| 洮南市| 巴楚县| 奎屯市| 禄劝| 红河县| 大荔县| 马尔康县| 内江市| 公安县| 陈巴尔虎旗| 呈贡县| 铜山县| 临泉县| 天水市| 景洪市| 平武县| 呼图壁县| 阿拉善左旗| 万州区| 长宁县| 永平县| 长顺县| 建阳市| 潜山县| 灌南县| 奇台县| 巴东县| 城口县| 易门县| 富平县| 尉犁县| 恩平市| 云浮市|