生成器有主要有四種方法:python
next()
執行函數,直到遇到下一個yield爲止,並返回值send(value)
爲生成器發送一個數值,next()方法就至關於send(None)close()
終止生成器throw(exc[exc_value,[exc_tb]])
在生成器yield處引起一個異常,close()至關於引起一個GeneratorExit異常一個斐波那契數列的例子bash
def fibonacci(): a, b = 0, 1 while True: yield b a, b = b, a+b a = fibonacci() for i in range(10): print a.next()
運行結果:函數
1 1 2 3 5 8 13 21 34 55 python2.7 fb.py 0.01s user 0.01s system 94% cpu 0.025 total
生成器每次生成一個數字並返回。ui
def reciver(): while True: n = (yield) print "Got %s" % n r = reciver() r.next() r.send(1) r.send('2')
運行結果:spa
Got 1 Got 2 python2.7 rec.py 0.01s user 0.01s system 86% cpu 0.023 total
這個模型能夠看作接收外部數據並進行處理。code
生成器可否接收send傳送來的數據,處理以後再返回呢?答案是確定的ci
def get(): n = 0 result = None while True: n = (yield result) result = n*10 t = get() t.next() for i in range(10): print t.send(str(i)) t.close()
運行結果get
0000000000 1111111111 2222222222 3333333333 4444444444 5555555555 6666666666 7777777777 8888888888 9999999999 python2.7 problem.py 0.02s user 0.00s system 83% cpu 0.024 total
固然生成器函數也是函數,也支持參數傳遞。generator
def countdown(n): print("counting down from %d" % n) while n > 0: yield n n -= 1 return c = countdown(10) print c.next() print c.next() for i in countdown(10): print i print sum(countdown(10))
運行結果string
counting down from 10 10 9 counting down from 10 10 9 8 7 6 5 4 3 2 1 counting down from 10 55
從上面的例子咱們發現,每次調用生成器函數要先執行next()
函數,而後才能發送數據, 若是忘記的話就會報錯。
TypeError: can't send non-None value to a just-started generator
這個有人容易忘記。這怎麼辦?用裝飾器來自動執行:
def coroutine(func): def start(*args,**kwargs): g = func(*args,**kwargs) g.next() return g return start @coroutine def reciver(): while True: n = (yield) print "Got %s" % n r = reciver() r.send(1) r.send('2')