生成器有主要有四种方法: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')