Python 函數與常用模組 - 產生器並行運算

來源:互聯網
上載者:User

標籤:傳回值   nis   pytho   老子   epoll   imp   大致   常用   儲存   

目前我們已經大致上都瞭解產生器了,但要怎麼實際應用呢?!接下來就要舉個例子

yield 儲存了這個函數的中斷狀態,返回當前這個狀態的值,並且把函數停在這,想什麼時候回來執行就什麼時候回來執行。

通過yield實現單綫程的情況下,實現並發運算的效果

#!/usr/bin/env python3# -*- coding:utf-8 -*-def consumer(name):    print("%s 準備吃包子啦!" %name)    while True:       baozi = yield  # baozi 沒有傳回值就會為none       print("包子[%s]來了,被[%s]吃了!" %(baozi,name))        c = consumer("Tony") c.__next__()             ---------------執行結果---------------Tony 準備吃包子啦!Process finished with exit code 0

產生一個消費者叫Tony,其實上面代碼就是一個產生器,所以要用 __next__() 這個方法去調用,但只有一個 __next__() 方法,程式會停在 baozi = yield 就結束了,那下面的就不會去執行了,那如果要繼續執行下面的話,要怎麼做呢?!

其實很簡單,在調用一次 __next__() 方法,就可以了

#!/usr/bin/env python3# -*- coding:utf-8 -*-def consumer(name):    print("%s 準備吃包子啦!" %name)    while True:       baozi = yield  # baozi 沒有傳回值就會為none       print("包子[%s]來了,被[%s]吃了!" %(baozi,name))        c = consumer("Tony") c.__next__() c.__next__()            ---------------執行結果---------------Tony 準備吃包子啦!包子[None]來了,被[Tony]吃了!Process finished with exit code 0

耶!包子被列印出來了,注意,包子變成none,而這個none是代表包子為空,當然就沒有包子可以吃,那要怎麼做一個包子給Tony?

#!/usr/bin/env python3# -*- coding:utf-8 -*-# import timedef consumer(name):    print("%s 準備吃包子啦!" %(name))    while True:       baozi = yield       print("包子[%s]來了,被[%s]吃了!" %(baozi,name))c = consumer("Tony")c.__next__()b1 = "韭菜餡"c.send(b1)---------------執行結果---------------Tony 準備吃包子啦!包子[韭菜餡]來了,被[Tony]吃了!Process finished with exit code 0

我們製作一個包子叫 b1 = "韭菜餡" ,並且透過 send() 這個方法來給Tony包子吃。

  • send() 其實就是去調用yield,同時也給它傳一個值。
  • __next__() 就只是去調用yield,並不會傳值給yield。

看下面代碼就可以更清楚瞭解

#!/usr/bin/env python3# -*- coding:utf-8 -*-import timedef consumer(name):    print("%s 準備吃包子啦!" %(name))    while True:       baozi = yield       print("包子[%s]來了,被[%s]吃了!" %(baozi,name))c = consumer("Tony")c.__next__()b1 = "韭菜餡"c.send(b1)c.__next__()---------------執行結果---------------Tony 準備吃包子啦!包子[韭菜餡]來了,被[Tony]吃了!包子[None]來了,被[Tony]吃了!Process finished with exit code 0

觀察一下,有發現第二個__next__() 的確沒有傳值,就只有去調用而已。

有沒有發現上面代碼裡面看起來很像二個任務在互動,所以接下來我們就把做包子的過程規範一點。

#!/usr/bin/env python3# -*- coding:utf-8 -*-import timedef consumer(name):    print("%s 準備吃包子啦!" %(name))    while True:       baozi = yield       print("包子[%s]來了,被[%s]吃了!" %(baozi,name))def producer(name):    c = consumer(‘A‘)    c2 = consumer(‘B‘)    c.__next__()    c2.__next__()    print("老子開始準備做包子啦!")    for i in range(10):        time.sleep(1)        print("做了1個包子分兩半!")        c.send(i)        c2.send(i)producer("tony")---------------執行結果---------------A 準備吃包子啦!B 準備吃包子啦!老子開始準備做包子啦!做了1個包子分兩半!包子[0]來了,被[A]吃了!包子[0]來了,被[B]吃了!做了1個包子分兩半!包子[1]來了,被[A]吃了!包子[1]來了,被[B]吃了!做了1個包子分兩半!包子[2]來了,被[A]吃了!包子[2]來了,被[B]吃了!做了1個包子分兩半!包子[3]來了,被[A]吃了!包子[3]來了,被[B]吃了!做了1個包子分兩半!包子[4]來了,被[A]吃了!包子[4]來了,被[B]吃了!做了1個包子分兩半!包子[5]來了,被[A]吃了!包子[5]來了,被[B]吃了!做了1個包子分兩半!包子[6]來了,被[A]吃了!包子[6]來了,被[B]吃了!做了1個包子分兩半!包子[7]來了,被[A]吃了!包子[7]來了,被[B]吃了!做了1個包子分兩半!包子[8]來了,被[A]吃了!包子[8]來了,被[B]吃了!做了1個包子分兩半!包子[9]來了,被[A]吃了!包子[9]來了,被[B]吃了!Process finished with exit code 0

單綫程下的並行效果就出來,實際上還是串列的,因為可以在不同的角色中切換,並且因為運行速度特別快,所以感覺上像是並行的,這個就是『異步IO』的雛形。

epoll的底層原理跟上面這個代碼差不多,本質上是這樣做的。

我們管上面這種代碼,叫『協程』,可以理解成最簡單的協程,也是一個典型的基本的生產者消費模型,簡單說,就理解成一個人在生產,一個在消費。

Python 函數與常用模組 - 產生器並行運算

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.