本质就是迭代器.
一个一个的创建对象 创建生成器的方式: 1. 生成器函数 2. 通过生成器表达式来获取生成器 3. 类型转换(看不到)生成器函数 (重点)
生成器函数中包含 yield , 返回数据和return差不多. return会立即结束这个函数的执行 yield 可以分段的执行一个函数生成器函数在执行的时候返回生成器. 而不是直接执行此函数
能向下执行的两个条件:
__next__(), 执行到下一个yield send(), 执行到下一个yield, 给上一个yield位置传值所有的生成器都是迭代器都可以直接使用for循环
都可以使用list()函数来获取到生成器内所有的数据生成器中记录的是代码而不是函数的运行
def func(): print("我的天哪 ")yield "宝宝"
gen = func() # 创建生成器. 此时运行会把生成器函数中的代码记录在内存
当执行到__next__(), 运行此空间中的代码, 运行到yield结束.优点: 节省内存, 生成器本身就是代码. 几乎不占用内存
特点: 惰性机制, 只能向前. 不能反复# def func():# print("我叫周润发")# return "林志玲" # return在函数中表示返回的意思### ret = func()# print("返回值是", ret)# 函数中包含了yield, 此函数就是生成器函数# 大坑: 生成器函数运行之后. 产生一个生成器. 而不是运行函数# def func():# print("我叫周润发")# yield "林志玲" # yield表示返回. 不会终止函数的执行# print("宝宝干嘛去了??")# yield "宝宝回来了"# print("宝宝你在干嘛?")# # yield "没了"## ret = func() # 执行函数, 此时没有运行函数.# # # 此时我们拿到的是生成器# # print("返回值是", ret) ### # 执行到下一个yield# print(ret.__next__()) # 第一次执行__next__此时函数才开始执行# print(ret.__next__()) # 执行到下一个yield# print(ret.__next__()) # StopIteration# 买衣服, JACK JONES 10000# def buy():# lst = []# for i in range(10000):# lst.append("衣服%s" % i)# return lst## lst = buy()# print(lst)# def buy():# for i in range(10000):# yield "衣服%s" % i## gen = buy() # 生成器或者迭代器的好处: 节省内存# # print(gen.__next__())# # print(gen.__next__())# # print(gen.__next__())## # for yifu in gen: 迭代器. __next__()# # print(yifu)## lst = list(gen) # 内部使用的是for循环 -> __next__()# print(lst)# send() -> __next__()# send()可以给上一个yield位置传值# def func():# print("韭菜盒子")# a = yield "韭菜鸡蛋"# print("a", a)# b = yield "韭菜西红柿"# print("b", b)# c = yield "火烧"# print("c", c)## gen = func()## print(gen.__next__()) # 第一个位置用send没有任何意义# print(gen.send("篮球")) # 给上一个yield位置传值# print(gen.send("足球"))# def eat():# print("我吃什么啊")# a = yield "馒头"# print("a=",a)# b = yield "⼤饼"# print("b=",b)# c = yield "⾲菜盒⼦"# print("c=",c)# yield "GAME OVER"## gen = eat() # 获取⽣成器## ret1 = gen.__next__()# print(ret1)# ret2 = gen.send("胡辣汤")# print(ret2)# ret3 = gen.send("狗粮")# print(ret3)# ret4 = gen.send("猫粮")# print(ret4)