Python中的協(xié)程和生成器很相似但又稍有不同。主要區(qū)別在于:
首先我們先來回顧下生成器的創(chuàng)建過程。我們可以這樣去創(chuàng)建一個(gè)生成器:
def fib():
a, b = 0, 1
while True:
yield a
a, b = b, a+b
然后我們經(jīng)常在for
循環(huán)中這樣使用它:
for i in fib():
print i
這樣做不僅快而且不會(huì)給內(nèi)存帶來壓力,因?yàn)槲覀兯枰闹刀际莿?dòng)態(tài)生成的而不是將他們存儲(chǔ)在一個(gè)列表中。更概括的說如果現(xiàn)在我們?cè)谏厦娴睦又惺褂?code>yield便可獲得了一個(gè)協(xié)程。協(xié)程會(huì)消費(fèi)掉發(fā)送給它的值。Python實(shí)現(xiàn)的grep
就是個(gè)很好的例子:
def grep(pattern):
print("Searching for", pattern)
while True:
line = (yield)
if pattern in line:
print(line)
等等!yield
返回了什么?啊哈,我們已經(jīng)把它變成了一個(gè)協(xié)程。它將不再包含任何初始值,相反要從外部傳值給它。我們可以通過send()
方法向它傳值。這有個(gè)例子:
search = grep('coroutine')
next(search)
#output: Searching for coroutine
search.send("I love you")
search.send("Don't you love me?")
search.send("I love coroutine instead!")
#output: I love coroutine instead!
發(fā)送的值會(huì)被yield
接收。我們?yōu)槭裁匆\(yùn)行next()
方法呢?這樣做正是為了啟動(dòng)一個(gè)協(xié)程。就像協(xié)程中包含的生成器并不是立刻執(zhí)行,而是通過next()
方法來響應(yīng)send()
方法。因此,你必須通過next()
方法來執(zhí)行yield
表達(dá)式。
我們可以通過調(diào)用close()
方法來關(guān)閉一個(gè)協(xié)程。像這樣:
search = grep('coroutine')
search.close()
更多協(xié)程相關(guān)知識(shí)的學(xué)習(xí)大家可以參考David Beazley的這份精彩演講。