python生成器generator介紹

巴扎黑
發布: 2017-07-17 15:54:35
原創
1527 人瀏覽過

  在跟著廖雪峰的博客學習python,看到生成器這一章節的時候,首先提到了generator 、yield,然後在搜索資料的時候,又查到了協程這一概念,這篇文章總結這幾個概念.

  generator  從字面上理解,就是生成器,它的實作方式有兩種:

1、不同於列表產生器([]),而是用 ()來表示。 (原來這個叫做生成器表達式哦,哈哈)

   存取方式,可以用for 循環來訪問,也可以用 .next 來存取。

N = ['Hello', 'World', 18, 'Apple', 'None']
hh = (s.lower() for s in N if isinstance(s,str) ==True)print hh#for item in hh:#    print item#print hh.next()#print hh.next()#print hh.next()#print hh.next()
登入後複製

輸出結果

at 0x7f543a074690>
hello
world
apple
none

hh 是生成器回傳的值,類似一個陣列。支援 for循環訪問和 .next()訪問,有一點需要注意的是,for 循環執行完了之後就不能執行 hh.next()了,類似於指針到了最後,或者C++中迭代器指向了最後,再訪問就會出現錯誤。

2、用yield來產生 ,(叫做生成器函數)

無論用next() 和for 循環來調用,都是執行到了yield之後,返回 n值,然後將當前的狀態掛起,然後返回。

def create_counter(n):print "create counter"#while True:while False:yield nprint 'increment n'n += 1cnt = create_counter(2)#print cntfor item in cnt:print item#print next(cnt)#print next(cnt)#print cnt.next()#print cnt.next()
登入後複製

例如這個範例中,當印cnt的時候,

#說明這是一個,生成器。
當 為False的時候,只會印出 create counter

當為True的時候,用for 循環就會出現死循環的情況。

協程:

我知道有行程、執行緒的概念,但是協程是什麼東西,我還真是不知道

從技術的角度來說,「協程就是你可以暫停執行的函數」。如果你把它理解成“就像生成器一樣”,那麼你就想對了。這是在一篇文章上看到的。

python之所以執行效率高

1、為子程式切換不是執行緒切換,而是由程式本身控制,因此,沒有執行緒切換的開銷,和多執行緒比,線程數量越多,協程的效能優勢就越明顯。

2、執行的過程中不會涉及到鎖定機制。

 附上一個簡單的生產者與消費者的例子:

def consumer():
    r = ''while True:
        n = yield rif not n:returnprint('[CONSUMER] Consuming %s...' % n)
        time.sleep(1)
        r = '200 OK'def produce(c):
    c.next()
    n = 0while n < 5:
        n = n + 1print('[PRODUCER] Producing %s...' % n)
        r = c.send(n)print('[PRODUCER] Consumer return: %s' % r)
    c.close()if __name__=='__main__':
    c = consumer()
    produce(c)
登入後複製

1. consumer函數是一個generator。  
2. c.send(None)其實等價於next(c),第一次執行時其實只執行到n = yield r就停止了,然後把r的值回傳給呼叫者。  
3. yield r是一個表達式,透過send(msg)被賦值,而send(msg)是有回傳值的,回傳值為:下一個yield r表達式的參數,即為r 。  
4. produce一旦生產了東西,透過c.send(n)切換到consumer執行。 consumer透過yield拿到訊息,處理,再透過yield把結果傳回。也就是說,c.send(1) 不但會給c 傳送一個數據,它還會等著下次yield 從c 中返回一個數據,它是有返回值的,一去一回才算完,拿到了傳回的資料(200 OK)才繼續下面執行。  
5. 整個流程無鎖,由一個執行緒執行,produce和consumer協作完成任務,所以稱為“協程”,而非執行緒的搶佔式多任務。

說,就是yield r 是表達式,透過c.send 被賦值,然後傳回值為下一個為yield r 表達式的參數。


 



######################################### #################

以上是python生成器generator介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!