# ### 生成器函数 ''' (用def定义,里面含有yield) # yield 类似于 return 共同点在于:执行到这句话都会把值返回出去 不同点在于:yield每次返回时,会记住上次离开时执行的位置 , 下次在调用生成器 , 会从上次执行的位置往下走 而return直接终止函数,每次重头调用. yield 6 和 yield(6) 2种写法都可以 yield 6 更像 return 6 的写法 推荐使用 ''' from collections import Iterator,Iterable # (1) 基本使用 '''如果函数当中包含了yield ,那么这个函数是生成器函数''' def mygen(): print("one") yield 1 print("two") yield 2 print("three") yield 3 # 初始化生成器函数 => 返回一个生成器对象 ,简称生成器 gen = mygen() print(isinstance(gen,Iterator)) # 调用生成器 res = next(gen) print(res) res = next(gen) print(res) res = next(gen) print(res) # res = next(gen) # print(res) ''' 代码解析: 首先初始化生成器函数 返回生成器对象 简称生成器 同过next进行调用 第一次调用时 print(one) yield 1 记录当前代码执行的位置状态,添加阻塞,暂停在这一行,并返回1,等待下一次调用 第二次调用时候 print(two) yield 2 记录当前代码执行的位置状态,添加阻塞,暂停在这一行,并返回2,等待下一次调用 第三次调用时候 print(three) yield 3 记录当前代码执行的位置状态,添加阻塞,暂停在这一行,并返回3,等待下一次调用 第四次调用时 因为没有yield 返回值了 所以直接报错.... ''' # (2) 优化代码 def mygen(): for i in range(1,101): yield "我的球衣号码是%d" % (i) # 初始化生成器函数 返回 生成器对象 简称生成器 gen = mygen() for i in range(50): res = next(gen) print(res) for i in range(30): res = next(gen) print(res) # (3) send 把值发送给上一个yield ''' ### send # next和send区别: next 只能取值 send 不但能取值,还能发送值 # send注意点: 第一个 send 不能给 yield 传值 默认只能写None 最后一个yield 接受不到send的发送值 ''' def mygen(): print("start") res = yield 1 print(res) res = yield 2 print(res) res = yield 3 print(res) print("end") # 初始化生成器函数 返回生成器 ''' send 在第一次调用的时候,必须给参数None gen.send(None) 是一个硬性要求的语法(因为第一次调用的时候,没有遇到上一个yield) ''' gen = mygen() res = gen.send(None) print(res) res = gen.send(111) print(res) res = gen.send(222) print(res) # res = gen.send(333) # print(res) ''' 第一次调用时 ,必须使用gen.send(None) print(start) res = yield 1 记录当前代码执行的位置状态 ,添加阻塞并返回1,等待下一次调用 第二次调用时 , send 先发送 , 在返回 , 发送给yield 1 res接收到了111这个值 print(111) res = yield 2 记录当前代码执行的位置状态 ,添加阻塞并返回2,等待下一次调用 第三次调用时 , send 先发送 , 在返回 , 发送给yield 2 res接收到了222这个值 print(222) res = yield 3 记录当前代码执行的位置状态 ,添加阻塞并返回3,等待下一次调用 第四次调用时, 因为没有yield 继续返回了 ,直接报错,越界错误 如果仍然想要执行后面没走完的代码,比如95 96 ,那么要通过try ... except 异常处理来解决 try: lst = [1,2] print(lst[99]) except: pass ''' ### yield from : 将一个可迭代对象变成一个迭代器返回 def mygen(): # yield ["陈桂涛","五金玲","张俊林"] yield from ["陈桂涛","五金玲","张俊林"] # 初始化一个生成器函数mygen 返回生成器 gen = mygen() res = next(gen) print(res) res = next(gen) print(res) res = next(gen) print(res) # 用生成器写斐波那契数列 # 1,1,2,3,5,8,13,21....... def mygen(n): a = 0 b = 1 i = 0 while i<n: # print(b) yield b a,b = b,a+b i+=1 gen = mygen(100000) for i in range(20): res = next(gen) print(res) ''' a = 0 b = 1 a,b = b,a '''