def test() :
yield 1
yield可以用来做返回值,也可以用来保留函数的运行状态。每一次__next__方法,运行都是从yield后开始运行的
生成器函数的好处
代码示例:
def product_baozi():
for i in range(100):
yield '一屉包子%s' %i
pro_g = product_baozi()
baozi1 = pro_g.__next__()
print('来了一个人吃包子', baozi1)
########一种不太行的迭代方法适用#########
def xiadan():
ret = []
for i in range(100):
ret.append('鸡蛋%s' %i)
return ret
print(xiadan())
#缺点1:占用空间大
#缺点2:效率低
#######改进措施#########################
alex_lmj = xiadan()
jidan = alex_lmj.__next__()
print('zhoushaochen取鸡蛋',jidan)
生成器总结
- 生成器在语法上和函数类似:生成器函数和常规函数几乎是一样的。它们都是使用def语句进行定义,但差别在于:生成器使用yield语句返回一个值,而常规函数使用return语句返回一个值
- 自动实现迭代器协议:对于生成器,Python会自动实现迭代器协议,以便应用到迭代背景中(如for循环,sum函数)。由于生成器自动实现了迭代器协议,所以我们可以调用它的next方法,并且在没有值可以返回的时候,生成器自动产生StopIteration异常
- 状态挂起:生成器使用yield语句返回一个值。yield语句挂起该生成器函数的函数,保留足够的信息,以便之后从它离开的地方继续执行(前提:使用生成器表达式)
代码示例
def get_population() :
with open('人口普查','r',encoding = 'utf-8') as f :
for i in f :
yield eval(i)
g = get_population()
s1 = g.__next__()
print(s1['population'])
all_pop = sum(eval(i)['population'] for i in g)
print(all_pop)
再次强调,迭代器只能使用一次!
迭代器实战:生产者消费模型——考虑实际需求,并发运行两个程序
def producer() :
ret = []
for i in range(100) :
ret.append('包子%s' %i)
return ret
def consumer(res) :
for index,baozi in enumerate(res) :
print('第%s个人,吃了%s' %(index,baozi))
res = producer()
consumer(res)
一个小点:关键字参数在默认参数之后输入