使用生成器,可以生成一个值的序列用于迭代,并且这个值的序列不是一次生成,而是使用一个,再生成一个,可以使程序节约大量的内存。
1、生成器的创建
生成器对象是通过使用 yield 关键字定义的函数对象,因此生成器也是一个函数;生成器用于生成一个序列以便在迭代器中使用。
生成器示例:
def myYield(n):
while n > 0:
print('开始生成...')
yield n
print('完成一次...')
n -= 1
if __name__ == '__main__':
for i in myYield(4):
print('遍历到的值:', i)
print('-------' * 2)
my_yield = myYield(3)
print('第一次调用')
print(my_yield.__next__())
print('第二次调用')
print(my_yield.__next__())
运行结果:
开始生成...
遍历到的值: 4
完成一次...
开始生成...
遍历到的值: 3
完成一次...
开始生成...
遍历到的值: 2
完成一次...
开始生成...
遍历到的值: 1
完成一次...
--------------
第一次调用
开始生成...
3
第二次调用
完成一次...
开始生成...
2
说明:每执行一次my_yield.__next__(),进入函数执行完yield n后停滞,下一次手动调用后继续执行;
2、生成器与协程
使用生成器的send()方法来重置生成器的生成序列,称为协程。
协程示例:
def myYield2(n):
while n > 0:
rcv = yield n
n -= 1
print(rcv, n)
if rcv is not None:
n = rcv
#if __name__ == '__main__':
my_yield = myYield2(3)
print(my_yield.__next__())
print(my_yield.__next__())
print('传给生成器值:')
print(my_yield.send(10))
print('---')
print(my_yield.__next__())
运行结果:
3
None 2
2
传给生成器值:
10 1
10
---
None 9
9
说明:调用send()方法后,将rcv赋值为10,继续执行知道执行完yield后挂起;若不使用send()方法,rcv的值为None。
若第一次使用的为send()方法,则必须传None否则程序报错。