python生成器
优点:不会一下子在内存中生成太多数据
''' 生成器案例 需要一个生产一个 可以使用g.__next__() 或for 循环来逐步获取 ''' def produce(): """生产衣服""" for i in range(2000000): yield "生产了第%s件衣服"%i product_g = produce() print(product_g.__next__()) #要一件衣服 print(product_g.__next__()) #再要一件衣服 print(product_g.__next__()) #再要一件衣服 num = 0 for i in product_g: #要一批衣服,比如5件 print(i) num +=1 if num == 15: break #到这里我们找工厂拿了8件衣服,我一共让我的生产函数(也就是produce生成器函数)生产2000000件衣服。 #剩下的还有很多衣服,我们可以一直拿,也可以放着等想拿的时候再拿
def generator(): print(123) content = yield 1 print('=======',content) print(456) yield 2 g = generator() ret = g.__next__() print('***',ret) ret = g.send('hello') #send的效果和next一样 print('***',ret) #send 获取下一个值的效果和next基本一致 #只是在获取下一个值的时候,给上一yield的位置传递一个数据 #使用send的注意事项 # 第一次使用生成器的时候 是用next获取下一个值 # 最后一个yield不能接受外部的值
''' 通过生成器实现平均数 循环输入新的数字,同时生成新的平均数 ''' def averager(): total = 0.0 count = 0 l=[] average = None while True: term = yield average,l#返回平均值,列表 l.append(term) total += term count += 1 average = total/count g_avg = averager() next(g_avg) print(g_avg.send(10)) print(g_avg.send(10)) print(g_avg.send(10)) #循环调用生成器 while True: num=input("新数字:") print(g_avg.send(int(num)))
''' 通过装饰器,执行next方法 使用语法糖调用 ''' def init(func): #在调用被装饰生成器函数的时候首先用next激活生成器 def inner(*args,**kwargs): g = func(*args,**kwargs) next(g) return g return inner @init def averager(): total = 0.0 count = 0 average = None while True: term = yield average total += term count += 1 average = total/count g_avg = averager() # next(g_avg) 在装饰器中执行了next方法 print(g_avg.send(10)) print(g_avg.send(30)) print(g_avg.send(5))
''' 两种生成器的下发实现相同的效果 ''' def gen1(): for c in 'AB': yield c for i in range(3): yield i print(list(gen1())) def gen2(): yield from 'AB' yield from range(3) print(list(gen2()))
''' next()和__next__本质是一样的 ''' egg_list=['鸡蛋%s' %i for i in range(10)] #列表解析 laomuji=('鸡蛋%s' %i for i in range(10))#生成器表达式 print(laomuji) print(next(laomuji)) #next本质就是调用__next__ print(laomuji.__next__()) print(next(laomuji))