def f():
for x in xrange(0, 5):
y = yield x
print y
g = f()
g.send(None)
上面是一個(gè)簡單的生成器衫贬,在第一次調(diào)用g.send(None)
的時(shí)候邻薯,生成器開始從頭一直執(zhí)行到y(tǒng)ield處(yield未返回)腊状,生成器暫停接剩,并攜帶生成器內(nèi)部的x返回到外部調(diào)用生成器的地方妖碉,也就是g.send(None)
返回了滔迈,而且返回值就是yield攜帶出來的x浙芙,如果我們再在生成器外部調(diào)用g.send('hello')
蹂风,那么這個(gè)調(diào)用會攜帶參數(shù)'hello'再次進(jìn)入到生成器暫停的地方喜命,里面的yield表達(dá)式會返回沟沙,而返回值就是在外部send進(jìn)去的參數(shù)'hello'.
從以上的過程可以看出,yield表達(dá)式可以即可以向生成器外部返回值壁榕,又可以接受外部傳進(jìn)來的值矛紫,最重要的是它可以在任意地方中斷函數(shù)的執(zhí)行又恢復(fù)回來,這些特性使得生成器像線程一樣可以與其他線程交互牌里,還可以被中斷颊咬,被調(diào)度,但是不像線程那樣會被隨機(jī)地中斷牡辽,生成器被中斷的地方是被顯示地規(guī)定了的喳篇,也就是yield出現(xiàn)的地方,而且這種中斷僅發(fā)生在語句和語句之間态辛,而不是像線程中斷那樣會發(fā)生在更小粒度的指令之間麸澜,這樣就不需要像線程那樣需要各種鎖來同步,有了生成器我們就可以在自己的控制下切換邏輯流奏黑。
實(shí)際上python中生成器便是協(xié)程炊邦,只不過生成器一般只是從內(nèi)部單向地向外發(fā)送數(shù)據(jù),而協(xié)程更強(qiáng)調(diào)內(nèi)部和外部的交互和調(diào)度熟史。