Python語言 生成器函式併發

2021-08-21 02:38:47 字數 3003 閱讀 8022

import time

def consumer(name):

print(name,'開始吃包子啦!')

while true:

food = yield #出入口

print(name,'吃了',food,end='')

def producer():

c1 = consumer('劉玄')

c2 = consumer('劉處玄')

c1.__next__()

c2.__next__()

for i in range(5):

time.sleep(1)

c1.send('肉包')

print(i+1,'個')

c2.send('菜包')

print(i + 1, '個')

producer()

執行結果:
劉玄 開始吃包子啦!

劉處玄 開始吃包子啦!

劉玄 吃了 肉包1 個

劉處玄 吃了 菜包1 個

劉玄 吃了 肉包2 個

劉處玄 吃了 菜包2 個

劉玄 吃了 肉包3 個

劉處玄 吃了 菜包3 個

劉玄 吃了 肉包4 個

劉處玄 吃了 菜包4 個

劉玄 吃了 肉包5 個

劉處玄 吃了 菜包5 個

以上**:實現了兩個函式併發執行。即乙個函式consumer負責吃包子,乙個producer函式負責製作包子。當製作出包子

就把包子派送給consumer,consumer接受到包子就開始執行吃。所以製作包子+吃包子是交替進行的。這樣給了我們乙個

印象,感覺製作包子和吃包子兩個函式都在執行。下面,你可以閱讀基本原理

可以這樣理解

之所以執行c1.__next__()是因為要執行consumer函式,使得它從yield這個出入口出來,出來是為了讓其他函式傳值到consumer函式的yield裡面,當傳值完成後,再次進入到consumer函式,取出yield裡面的值,供consumer函式之後的**用,因為這裡是while不斷迴圈的,所以遇到有yield時又會出去,直到有其他函式執行了c1.send***)才再次進入consumer函式

可能大家不明白,為什麼要執行下面的**:

c1.__next__()
c1.send('肉包')
這句**已經說明派送包子已經知道要派送給誰,執行c1.__next__()

有什麼意義呢。

執行這句話的目的,可以理解雖然生產者producer知道做好的包子派送給誰,但是它並不知道這位顧客有沒有需求,也就是顧客先有需求,生產者再有供給。當這句話執行後,啟用了消費者consumer函式,然後消費者提出了需求,也就是執行到yield處,需要生產者往裡面放包子,所以此時,消費者處於等待狀態。此時,就會跳轉到生產者函式裡面,生產者已經知道了顧客的需求,然後派送(send()函式)才能有效

其他的內容:
1.next()不能傳遞特定的值,只能傳遞none進去2.send()可以傳遞yield表示式的值進去3.對於普通的生成器,第乙個next呼叫,相當於啟動生成器,會從生成器函式的第一行**開始執行,直到第一次執行完yield語句(第4行)後,跳出生成器函式。4.需要提醒的是,第一次呼叫時,請使用next()語句或是send(none),不能使用send傳送乙個none的值,否則會出錯的,因為沒有python yield語句來接收這個值。

python生成器函式 Python 生成器函式

一 生成器 生成器指的是生成器物件,可由生成器表示式得到,也可使用 yield 關鍵字得到乙個生成器函式,呼叫這個函式得到乙個生成器物件 生成器物件,是乙個可迭代物件,是乙個迭代器 生成器物件,是延遲計算 惰性求值的 1.1 生成器函式 函式體重包含 yield 語句的函式,就是生成器函式,呼叫後返...

python 生成器函式

python 函式的定義體中有 yield 關鍵字,該函式就是生成器函式。呼叫生成器函式時,會返回乙個生成器物件。生成器函式的定義體執行完畢後,生成器物件會丟擲stopiteration 異常。def gen a print start yield 1 print starting yield 2 ...

python函式 生成器

1.生成器 是乙個特殊的迭代器 迭代的抽象層級更高 所以,擁有迭代器的特性,惰性計算資料,節省記憶體。能夠記錄下狀態,並通過next 函式,訪問下乙個狀態。具備可迭代性。但是,如果打造乙個自己的迭代器,比較複雜,需要實現很多方法 在後續的面相物件程式設計中會講解 所以,就有乙個更加優雅的方式 生成器...