• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            為生存而奔跑

               :: 首頁 :: 聯系 :: 聚合  :: 管理
              271 Posts :: 0 Stories :: 58 Comments :: 0 Trackbacks

            留言簿(5)

            我參與的團隊

            搜索

            •  

            積分與排名

            • 積分 - 326856
            • 排名 - 74

            最新評論

            閱讀排行榜

            評論排行榜

            轉自 http://lukejin.javaeye.com/blog/587051


            前段時間在讀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 = 01            
            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關鍵字的函數就是一個生成器函數,被調用的時候生成一個可以控制自己運行的迭代器




            實驗:

            生成器并不是事先生成所有的結果,而是需要時生成



            def fib(max):
                a, b 
            = 0, 1
                
            while a < max:
                    
            yield a
                    
            print 'yield'
                    a, b 
            = b, a+b

            for n in fib(10):
                
            print 'for'
                
            print n

            運行結果

            for
            0
            yield
            for
            1
            yield
            for
            1
            yield
            for
            2
            yield
            for
            3
            yield
            for
            5
            yield
            for
            8
            yield


            posted on 2011-03-15 23:11 baby-fly 閱讀(2011) 評論(1)  編輯 收藏 引用 所屬分類: Python

            Feedback

            # re: 從python的yield說起[未登錄] 2011-08-17 22:34 哈哈
            很清楚,謝謝  回復  更多評論
              

            久久久91精品国产一区二区三区 | 久久99精品久久久久久久久久| yy6080久久| 亚洲人成伊人成综合网久久久| 久久亚洲私人国产精品vA| 97久久超碰国产精品2021| 伊人丁香狠狠色综合久久| 亚洲人成网站999久久久综合| 久久中文字幕精品| 97久久精品无码一区二区| 国产精品99久久久久久猫咪| 久久笫一福利免费导航 | 久久精品一区二区影院| 性做久久久久久久久浪潮| 久久精品国产亚洲av麻豆小说| 国产精品VIDEOSSEX久久发布| 漂亮人妻被中出中文字幕久久 | 人妻无码精品久久亚瑟影视| 日本久久久精品中文字幕| 久久经典免费视频| 大美女久久久久久j久久| 亚洲欧美伊人久久综合一区二区 | 热综合一本伊人久久精品| 久久A级毛片免费观看| 人妻无码精品久久亚瑟影视| 久久久久国产亚洲AV麻豆| 97久久综合精品久久久综合| 亚洲色欲久久久综合网| 久久久久久久久久久| 欧美精品福利视频一区二区三区久久久精品| 久久婷婷成人综合色综合| 久久精品国产清自在天天线| 婷婷久久综合九色综合九七| 久久精品二区| 亚洲国产精品成人AV无码久久综合影院 | 国产免费久久精品99久久| 99久久er这里只有精品18| 精品多毛少妇人妻AV免费久久| 久久99精品久久久久久噜噜| 日本免费久久久久久久网站| 久久夜色tv网站|