1、何为生成器?
在Python中,使用了yield的函数称之为生成器(Generator),调用这个生成器函数,在遇到yield后并不会执行后面的代码,而是返回一个迭代器对象,因此也可以说生成器就是自定义迭代器!
2、为何用生成器?
上节学习中,我们知道迭代器只能转换已存在的可迭代对象,如需直接创造对象只能自定义迭代器了!
自定义迭代器就是要自定义工具,说到工具就免不了用函数了,我们需要返回值但又不能用return,所以有了yield,就会转换成生成器
在函数内一旦存在yield关键字,调用函数并不会执行函数体代码,而是返回一个生成器对象,即自定义迭代器,当赋值变量后调用next方法会触发函数体代码运行,然后遇到yield暂停,而后将yield后跟的值当做本次调用的结果返回
3 、如何用生成器?
如下所示,调用next方法,代码运行到yield时挂起,并将yield后面的值返回!当使用close后,结束
def test_generator():
yield 666
yield 577
yield 568
var_generator = test_generator()
print(var_generator.__next__())
print(var_generator.__next__())
var_generator.close()
print(var_generator.__next__())
# 执行得到结果
666
577
Traceback (most recent call last):
File "/home/sanxi/PycharmProjects/untitled1/test.py", line 10, in <module>
print(var_generator.__next__())
StopIteration
下面来模仿下range
def my_range(start, stop, step=1):
print('start...')
while start < stop:
yield start
start += step
print('stop...')
var_range = my_range(1,5)
for i in var_range:
print(i)
# 执行得到结果
start...
1
2
3
4
stop...
4、yield表达式
4.1、yield与return区别
- return仅返回一次,yield可多次返回值。
- 代码遇到return会结束运行,而yield则是挂起
4.2、next与send
如下所示,当yield后面没有定义值,且yield赋予给一个变量时,函数体代码并不会执行,需要初始化后才可以!
初始化方式可以是next也可以是send(None)
def lunch():
food = yield
sanxi_lunch = lunch()
print(sanxi_lunch.__next__())
# 执行得到结果
None
初始化完成后再用send为yield传值
def lunch():
print('starting...')
while True:
food = yield
print(f'should eat a lot of {food}')
sanxi_lunch = lunch()
sanxi_lunch.__next__() #初始化生成器
sanxi_lunch.send('rice') #为yield传值并将其赋予给左边的变量名
print(sanxi_lunch.__next__()) #再次循环,无传值,则默认返回None
sanxi_lunch.send('meat') #为yield传值
sanxi_lunch.close() #相当于关闭迭代器,即销毁
print(sanxi_lunch.__next__())
# 执行得到结果
starting...
should eat a lot of rice
should eat a lot of None
None
should eat a lot of meat
Traceback (most recent call last):
File "/home/sanxi/PycharmProjects/untitled1/test.py", line 13, in <module>
print(sanxi_lunch.__next__())
StopIteration