对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个Stoplteration 异常,终止迭代(只能往后不能往前退)。
for循环中,调用对象__iter__()方法,将其变成遵循迭代器协议的迭代对象,再通过其内部的__next__()方法进行依次访问,从而达到遍历效果。
可以理解为数据类型,这种数据类型自动实现了迭代器协议(其他数据类型需要调用自己内置的__iter__方法),生成器就是可迭代对象。
运行生成器方法:
生成器表现形式:(generatorobject 生成器对象)
L = [x + 1 for x in range(10)]
print(L)
# 输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
基本语法:
def 函数名():
yield 返回值
yield 返回值
# yield 特性:与return相同,可以yield多次,可以保存状态。
yield 语句是生成器中的关键语句,生成器在实例化时并不会被执行,而是等待调用其__next__()方法才开始运行。并且当程序运行完yield语句后就会“吼(hold)住”,即保持当前状态且停止运行,等待下一次遍历时才恢复运行,并会把 .send(参数) 中的参数传回到yield。
生成器案例:生产者、消费者模型(吃包子案例)
# 吃包子
def conSumer(name):
print('我是[%s],准备开始吃包子了!' % name)
while True:
baozi = yield
print('%s 很开心的把 [%s] 吃掉了。' % (name,baozi))
# 生成包子
def producer():
c1 = conSumer('tt')
c1.__next__()
for i in range(10):
c1.send('包子%s' % i)
producer()
执行结果:
我是[tt],准备开始吃包子了!
tt 很开心的把 [包子0] 吃掉了。
tt 很开心的把 [包子1] 吃掉了。
tt 很开心的把 [包子2] 吃掉了。
tt 很开心的把 [包子3] 吃掉了。
tt 很开心的把 [包子4] 吃掉了。
tt 很开心的把 [包子5] 吃掉了。
tt 很开心的把 [包子6] 吃掉了。
tt 很开心的把 [包子7] 吃掉了。
tt 很开心的把 [包子8] 吃掉了。
tt 很开心的把 [包子9] 吃掉了。