python-02-生成器

'''
1.生成器是一个以yield带返回值的函数,它需要用__next__()或send()接收yield返回的值时才可执行该函数.
而迭代器不一定是个函数,它只是需要__next__来取迭代器内的值.
一个__next__()或send()执行的代码只是该yield到其上一个yield之间的代码
eg:
def func():
print('我是')
yield 12
print('你爸')
yield 34
print('你爷爷')
yield 56
print(func().__next__()) # 执行的是第一个 yield 12 以上的代码,也即只会执行 print('我是')
print(func().__next__()) # 执行的是第二个 yield 34 到yield 12 之间的代码 print('你爸')

2.return与yield的区别:
(1)都可以返回函数值,但yield拿到的是一个生成器
(2)return可以终止程序,但yield不可以
(3)函数中如果有yield,则这个函数就可以说是生成器函数

3.生成器本质为一个迭代器,需要用__next__()才能得到数据,其数据为yield的返回值,以及执行其上的代码,否则只能得到一个地址.
eg:
def func():
yield 1
gen = func() # func(): 生成器函数名() 得到的只是一个生成器,这个时候并不会执行函数,也即func不会被执行
ret = gen.__next__() # 用 生成器.__next__() 才可以得到数据.其中 gen.__next__() 表示执行到下一个yield.且gen.__next__()
得到的是yield的返回值.也即 gen.__next__() = 1

4.生成器函数必须以yield结尾,否则会出错:
eg:
def func():
print('我是')
yield 123
print('你爸')
# 函数没有以yield结尾,会出错!

5.除__next__()方法可以获取生成器内的值外,send()方法也可以获取生成器内的值,且send()可以给上一个yield传值
eg:
def func():
print('我是', end='')
a = yield 456
print(func().__next__()) # 得到结果为: 我是 456
print(func().send('你爸')) # 原理上讲send会把 '你爸' 这个值传递给a,但我实践时成功不了
注:(1)send()中的参数不能呢个为空
(2)send()不可以取代第一个__next__(),因为第一个__next__没有上一个yield
(3)最后一个yield不可以用send()进行传值,因为最后一个yield没有下一个yield了,而send和__next__都是取下一个yield,都没有下一个了
那send还怎么在取的同时给上一个,也就是最后一个yield传值?

6.生成器对大规模集成数据进行处理时,会比return更节省空间:
eg: # 假如学校要给学生定校服,a学生要定一套,则给订单加个1
def order():
for i in range(10000):
yield '衣服+str(i)'
a = order().__next__()


'''
原文地址:https://www.cnblogs.com/gongteng/p/13567574.html