python基础-生成器
什么是生成器
# 知乎链接:https://www.zhihu.com/question/20829330
# 生成器:生成器是一种迭代器,是一种特殊的函数,使用yield操作将函数构造成迭代器。 # 简单概念:函数+yield # 普通的函数有一般有一个入口,有一个返回值;生成器有多个入口,多个返回值。 # 生成器的作用:延迟器,需要的时候再拿值,适合大数据量处理;节省内存压力
生成器与一般函数比较
# 一般函数与生成器的比较 # 写一个生成器 def hello(): print("hello") yield hello # 写一个函数 def hello1(): print("hello1") return hello1 h=hello() print(h) print(next(h)) print(type(h)) # <generator object hello at 0x10f7bceb8> # hello # <class 'generator'> h1=hello1() print(h1) print(type(h1)) # hello1 # <function hello1 at 0x10f7c0b70> # <class 'function'> # 太明显了,一般我们打印一个函数名+()就会打印函数执行的结果,是个很明确的结果 # 但是同样是函数名+()打印出来的是一个生成器对象,不是一个明确的结果,要想得到一个明确的结果必需是next(生成器对象obj)
from collections import Iterator def htest(): print("hello,yield") yield ["hekllo",'hh'],["hhh"] print("two") yield 1,2,3,4 print("three") yield "helo","word","hahh" print("four") yield 5,6 print("five") yield 5 #g 是什么,g就是生成器对象,iter是可迭代对象所有,next是迭代器所有,方法里就放迭代器里的对象 g=htest() print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g)) #print(next(g)) #超出范围,报错,stopIteraton,我们这里是手动调用,目的在于看清,他能记清楚上次的位置,每次自动输出下一个 # 注意:next()里放的是生成器对象,生成器对象,生成器对象,函数名+()
生成器举例
def init(func): print("hello1") def wrapper(*args,**kwargs): res=func(*args,**kwargs) next(res) return res return wrapper @init def eater(name): print("name:%s,start to eat"%name) food_list=[] while True: food=yield food_list print("%s eat %s"%(name,food)) food_list.append(food) print("done") e=eater("alex") e.send("鲍鱼仔") e.send("鱿鱼仔") e.send("章鱼仔") e.send("墨鱼仔") # 生成器: # haha=(x**2 for x in range(5)) # print(next(haha)) # print(next(haha)) # print(next(haha)) # print(next(haha)) # print(next(haha)) def gen(n): for i in range(n): yield i**2 for i in gen(5): print(i) # 如果直接对文件对象调用 read() 方法,会导致不可预测的内存占用。 # 好的方法是利用固定长度的缓冲区来不断读取文件内容。 # 通过 yield,我们不再需要编写读文件的迭代类,就可以轻松实现文件读取: def gen1(n): a=[] for i in range(n): a.append(i**2) return a for i in gen1(5): print(i)