非同步IO 協程回顧yield from

2021-10-04 22:55:36 字數 3235 閱讀 3254

咱先看看yield和yield form 的區別在哪兒,**如下,全部傳入range(10)

def g1(iterable):

yield iterable

def g2(iterable):

yield from iterable

for value in g1(range(10)):

print(value)

for value in g2(range(10)):

print(value)

結果: yield 輸出的是range(10),而yield from 輸出了他的迭代資料.

range(0, 10)01

2345

6789

在學習yield from之前先認識乙個庫 : chain ,這個庫可以迭代任意多個資料,包括list,dict,等等.

from itertools import chain 

my_list = [1,2,3]

my_dict =

for value in chain(my_dict,my_list,range(5,10)):

print(value)

它實現的功能是這樣的,把其中的資料都乙個個的迭代出來

bobby

bobby212

3567

89

現在我們自己實現乙個chain

# 自定義乙個chain

def my_chain(*args,**kwargs):

for my_iterable in args:

for value in my_iterable:

yield value

for value in my_chain(my_dict,my_list,range(5,10)):

print(value)

產生的值也是

bobby

bobby212

3567

89

現在呢,用yield from 實現一下

def my_chain(*args,**kwargs):

for my_iterable in args:

yield from my_iterable # yield from可以迭代其中的所有資料

for value in my_chain(my_dict,my_list,range(5,10)):

print(value)

生成的結果如下,yield from 簡化了上面的**,其實yield from 不止做到了迭代所有的資料,它內部實現了很多異常的處理

bobby

bobby212

3567

89

而且使用yield from 的使用方法,,他會在呼叫方和子生成器之間建立乙個雙向通道,他們實現連線

def g1(gen):

yield from gen

def main():

g = g1()

g.send(none)

# main 呼叫方 g1(委託生成器),gen子生成器

# yield from 會在呼叫方和子生成器之間建立乙個雙向通道

這是乙個yield from實戰的例子, 

final_result = {}

def sales_sum(pro_name):

total = 0

nums =

while true:

x = yield

print(pro_name+"銷量:",x)

if not x:

break

total+=x

return total,nums

def middle(key):

while 1:

final_result[key] = yield from sales_sum(key)

print(key+"銷量統計完成!")

def main():

data_set =

for key,data_set in data_set.items():

print("start key",key)

m = middle(key)

m.send(none) # 預啟用middle協程

for value in data_set:

m.send(value) # 給協程傳遞每一組的值

m.send(none)

print("final_result",final_result)

"""# 詳細剖析

"""def sales_sum1(pro_name):

total = 0

nums =

while true:

x = yield

print(pro_name+"銷量:",x)

if not x:

break

total+=x

return total,nums

if __name__ == '__main__':

my_gen =sales_sum1("boobby牌手機")

my_gen.send(none)

my_gen.send(1000)

my_gen.send(1300)

my_gen.send(1200)

try:

my_gen.send(none)# 會異常,把返回值顯示出來

except stopiteration as e:# 需要處理異常

result = e.value

print(result) # yield from會實現這些功能處理異常並返回值

它最終實現的效果是這樣的,大家可以拷貝上面的**,到ied中自己分析執行一下.這就涉及到了上面的上面yield from的使用方法.涉及到了呼叫方,委託生成器和子生成器,並且子生成器會和呼叫方實現乙個雙向通道.

boobby牌手機銷量: 1000

boobby牌手機銷量: 1300

boobby牌手機銷量: 1200

boobby牌手機銷量: none

(3500, [1000, 1300, 1200])

非同步I O 協程

什麼是協程呢?協程 coroutines 是一種比執行緒更加輕量級的存在,正如乙個程序可以擁有多個執行緒一樣,乙個執行緒可以擁有多個協程。協程不是被作業系統核心所管理的,而是完全由程式所控制,也就是在使用者態執行。這樣帶來的好處是效能大幅度的提公升,因為不會像執行緒切換那樣消耗資源。協程不是程序也不...

python協程與非同步協程

在前面幾個部落格中我們一一對應解決了消費者消費的速度跟不上生產者,浪費我們大量的時間去等待的問題,在這裡,針對業務邏輯比較耗時間的問題,我們還有除了多程序之外更優的解決方式,那就是協程和非同步協程。在引入這個概念之前我們先看 看這個圖 從這個我們可以看出來,假如來了9個任務,即使我們開了多程序,在業...

Python Demo18 非同步IO之協程

協程是通過generator來實現的,就是yield關鍵字和send 函式的使用。yield關鍵字可以將值 資訊 返回,同時在資訊返回後使程式停留在當前行。def test number 1.while true number 2.yield number print yield下面的 t test...