python之 yield --- 「協程」

在編程中咱們常常會用到列表,之前使用列表時須要聲明和初始化,在數據量比較大的時候也須要把列表完整生產出來,例如要存放1000給數據,須要準備長度1000的列表,這樣計算機就須要準備內存放置這個列表,在Python中,這種一邊循環一邊計算的機制,稱爲生成器:generator,這個功能在列表使用時比較節省空間,使用方法:編程

g=(i*2 for i in range(10))
data=g.__next__()
print(d)

取列表時data=g.__next__(),此時纔去生成。併發

應用:生成斐波拉契數列函數

def fig(num):
    n,a,b=0,0,1
    while n<num:
        yield b
        a,b=b,a+b
        n+=1
    return 'done'

fig(10) 定義長度爲10的數列spa

fig(10)
for i in range(10):
    try:
        x=next(g)
        print(x)
    except StopIteration as e:
        print('error %s' % e.value)
        break

運行結果:
1
1
2
3
5
8
13
21
34
55線程

這裏,最難理解的就是generator和函數的執行流程不同。函數是順序執行,遇到return語句或者最後一行函數語句就返回。而變成generator的函數,在每次調用next()的時候執行,遇到yield語句返回,再次執行時從上次返回的yield語句處繼續執行。code

還可經過yield實如今單線程的狀況下實現併發運算的效果blog

import time

def customer(name):
    print('%s要吃包子' %name)
    while True:
        baozi=yield
        print('%s包子來了,很快就被%s吃了' %(baozi,name) )
    return '出錯了'     #拋出異常

def producter(name,student,num):
    g=customer(student)   #**要吃包子
    g.__next__()
    print('%s廚師瞭解到%s要吃包子,開始作包子' %(name,student))
    for i in range(num):
        time.sleep(1)         #用時1秒
        g.send('韭菜餡')      #包子作好,送給學生
    print('包子賣完了')

#張廚師,學生今天中午吃包子,用10斤面作20個包子
producter('張廚師','學生',10)

運行結果:內存

學生要吃包子
張廚師廚師瞭解到學生要吃包子,開始作包子
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
韭菜餡包子來了,很快就被學生吃了
包子賣完了generator

相關文章
相關標籤/搜索