首頁 > 後端開發 > Python教學 > 實例詳解python生成器協程運算

實例詳解python生成器協程運算

巴扎黑
發布: 2017-09-05 11:11:20
原創
1220 人瀏覽過

下面小編就為大家帶來一篇python 生成器協程運算實例。小編覺得蠻不錯的,現在就分享給大家,也給大家做個參考。一起跟著小編過來看看吧

一、yield運行方式

我們定義一個如下的生成器:


def put_on(name):
 print("Hi {}, 货物来了,准备搬到仓库!".format(name))
 while True:
  goods = yield
  print("货物[%s]已经被%s搬进仓库了。"%(goods,name))
 
p = put_on("bigberg")
 
#输出
G:\python\install\python.exe G:/python/untitled/study4/test/double.py
 
Process finished with exit code 0
登入後複製

當我們把一個函數透過yield轉換成生成器,直接執行函數是不會出現結果回傳的。因為此時函數已經是個生成器了,我們要透過next()來取得值,並且在遇到yield時再次跳出函數。


print(type(p))
 
#输出
<class &#39;generator&#39;>
登入後複製

我們加入next()方法:


def put_on(name):
 print("Hi {}, 货物来了,准备搬到仓库!".format(name))
 while True:
  goods = yield  #遇到yield中断
  print("货物[%s]已经被%s搬进仓库了。"%(goods,name)) #中断后运行部分
 
p = put_on("bigberg")
p.__next__()
 
#输出
Hi bigberg, 货物来了,准备搬到仓库!
登入後複製

此時函數中斷在goods = yield 的地方,當我們再次呼叫next()函數時,函數只會執行中斷以後的內容,也就是上例中的yield下面部分。

我們再加入一個next():


def put_on(name):
 print("Hi {}, 货物来了,准备搬到仓库!".format(name))
 while True:
  goods = yield
  print("货物[%s]已经被%s搬进仓库了。"%(goods,name))
 
p = put_on("bigberg")
p.__next__()
p.__next__()
 
#输出
Hi bigberg, 货物来了,准备搬到仓库!
货物[None]已经被bigberg搬进仓库了。
登入後複製

我們可以第二次next()運行的是yield下面的部分內容,但並沒有給goods傳值,所以貨物是None。

小結:

透過yield將函數轉換為生成器,需要使用next()方法才能執行

yield只是保留函數的中斷狀態,再呼叫next()會執行yield後面的部分

yield如果沒有回傳值,會回傳一個None空值

二、send()傳值


def put_on(name):
 print("Hi {}, 货物来了,准备搬到仓库!".format(name))
 while True:
  goods = yield
  print("货物[%s]已经被%s搬进仓库了。"%(goods,name))
 
p = put_on("bigberg")
p.__next__()
p.send("瓜子")
 
#输出
Hi bigberg, 货物来了,准备搬到仓库!
货物[瓜子]已经被bigberg搬进仓库了。
登入後複製

##小結:

__next__()只是呼叫這個yield,也可以說成是喚醒yield,但不不會給yield傳值。

send()方法呼叫yield是,能給yield傳值

使用send()函數之前必須使用__next__(),因為先要中斷,當第二次呼叫時,才可傳值。


def put_on(name):
 print("Hi {}, 货物来了,准备搬到仓库!".format(name))
 while True:
  goods = yield
  print("货物[%s]已经被%s搬进仓库了。"%(goods,name))
 
p = put_on("bigberg")
p.__next__()
p.send("瓜子")
p.send("花生")
p.send("饼干")
p.send("牛奶")
 
#多次调用send()
Hi bigberg, 货物来了,准备搬到仓库!
货物[瓜子]已经被bigberg搬进仓库了。
货物[花生]已经被bigberg搬进仓库了。
货物[饼干]已经被bigberg搬进仓库了。
货物[牛奶]已经被bigberg搬进仓库了。
登入後複製

三、單一執行緒實作並行效果(協程)


import time
 
 
def put_on(name):
 print("Hi {}, 货物来了,准备搬到仓库!".format(name))
 while True:
  goods = yield
  print("货物[%s]已经被%s搬进仓库了。"%(goods,name))
 
 
def transfer(name):
 p = put_on(&#39;A&#39;)
 p2 = put_on(&#39;B&#39;)
 p.__next__()
 p2.__next__()
 print("%s将货物送来了!"%name)
 for i in range(5):
  time.sleep(1)
  print("%s递过来两件货物"%name)
  p.send("瓜子")
  p2.send("花生")
 
transfer("bigberg")
 
#输出
Hi A, 货物来了,准备搬到仓库!
Hi B, 货物来了,准备搬到仓库!
bigberg将货物送来了!
bigberg递过来两件货物
货物[瓜子]已经被A搬进仓库了。
货物[花生]已经被B搬进仓库了。
bigberg递过来两件货物
货物[瓜子]已经被A搬进仓库了。
货物[花生]已经被B搬进仓库了。
bigberg递过来两件货物
货物[瓜子]已经被A搬进仓库了。
货物[花生]已经被B搬进仓库了。
bigberg递过来两件货物
货物[瓜子]已经被A搬进仓库了。
货物[花生]已经被B搬进仓库了。
bigberg递过来两件货物
货物[瓜子]已经被A搬进仓库了。
货物[花生]已经被B搬进仓库了。
登入後複製

以上是實例詳解python生成器協程運算的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板