1、生成器函数
1)生成器指的是生成器对象,可以有生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器对象。(只要有yield就是生成器函数,调用的时候返回的就是生成器对象,一般都是放在for 循环后面的。) 与之对应的 (预热,预加载,一次性返回所有的值,缓存。)
生成器函数:
函数体内包括yield语句的函数,返回生成器对象,
生成器对象,是一个可迭代对象,是一个迭代器。
生成器对象,是延迟计算、惰性求值。
2)def inc():
for i in range(5):
yield i
print(type(inc()))
print(type(inc()))
x = inc()
print(type(inc()))
print(type(inc()))
for m in x:
print(m,'*')
for m in x:
print(m,'*')
普通函数的调用fn(),函数会立即执行完毕,但是生成器函数可以使用next函数进行多次执行。
生成器函数等价于生成器表达式,只不过生成器函数可以更加的复杂。
def gen():
print('line1')
yield 1
print('line2')
yield 2
print('line3')
return 3
next(gen())
next(gen())
g=gen()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g),'end')
3)在生成器函数中,使用多个yield语句,执行一次后暂停执行,把yield表达式的值返回。
再次执行会执行下一个yield语句。
Return语句依然可以终止函数,单return语句的返回值不会被获取的到。
Return会导致无法继续获取下一个值,抛出stopiteration异常。
如果函数没有显示的return语句,如果生产器函数执行到结尾,一样会抛出异常的。
4)生成器函数总结:
包含yield语句的生成器函数生成生成器对象的时候,生成器函数不会立即被执行。
Next(generator)会从函数的当前位置向后执行到碰到的第一个yield语句,会弹出值,并暂停函数执行。
再次调用next函数,和上一条一样的处理过程。
没有多余的yield语句能被执行,继续调用next函数,会抛出异常的。stopiteration
Generator生成器对象。
2、生成器应用
def counter():
i = 0
while True:
i += 1
yield i
def inc(c):
return next(c)
c = counter()
print(inc(c))
print(inc(c))
返回结果为 1,2 因为给counter赋值c了,每次重新调用的时候提前使用
def counter():
i = 0
while True:
i +=1
yield i
def inc():
c= counter()
return next(c)
print(inc())
print(inc())
print(inc())
返回结果为1,1.print的时候是三个不同的对象。
def counter():
i = 0
while True:
i +=1
yield i
def inc():
c= counter()
return next(c)
print(inc())
print(inc())
print(inc())
def inn():
def counter():
i = 0
while True:
i +=1
yield i
c = counter()
return lambda:next(c)
foo = inc()
print(foo())
print(foo())
上式和下式是等同的。
2)协程coroutine
生成器的高级用法
比进程、线程轻量级。 是在用户空间调度函数的一种实现。
Python3 asyncio就是协程实现,已经加入到标准库。
Python3.5中使用async,await关键字职业原生支持协程。
协程调度器实现思路
有两个生成器a和b
Next(A)后,A执行到了yield语句暂停,然后执行next(B),b执行到yield语句也暂停,然后再次调用next(a),在调用next(B),周而复始,就实现了调度的效果。
可以引用调度的策略来实现切换方式。
协程是一种非抢占式调度。
3)yield from:
For x in range(100)
Yield x
等价于
yield from range(100)
def inc():
for x in range(1000):
yield x
foo = inc()
print(next(foo))
print(next(foo))
print(next(foo))
def inc():
yield from range(1000)
foo = inc()
print(next(foo))
print(next(foo))
print(next(foo))
yield from 是python3.3出现的新的语法。
yield from iterable是for item in iterable:yield item形式的语法糖。
从迭代对象中一个个拿元素。
def counter(n):
for x in range(n):
yield x
def inc(n)