生成器函数

# ###  生成器函数   
'''
 (用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
'''

  

原文地址:https://www.cnblogs.com/huangjiangyong/p/10908002.html