利用迭代器,我们可以在每次迭代获取数据(通过next()方法)时按照特定的规律进行生成。但是我们在实现一个迭代器时,关于当前迭代到的状态需要我们自己记录,进而才能根据当前状态生成下一个数据。为了达到记录当前状态,并配合next()函数进行迭代使用,我们可以采用更简便的语法,即生成器(generator)。

""" *生成器是一类特殊的迭代器。"""

创建生成器方法 1

要创建一个生成器,有很多种方法。第一种方法很简单,只要把一个列表生成式的 [ ] 改成 ( )

# g = [i for  i in range(1,101)]            #列表
# print(g)

g = (i for i in range(1, 101))  # 生成器
print(g)  # 生成器<generator object <genexpr> at 0x00F60EF0>

# 方法1 for循环
# for i in g:
#     print(i)
# 方法2 for 循环的本质
# while True:
#     try:
#         print(next(g))
#     except StopIteration as e:
#         break
# 方法3 列表 元祖
# print(list(g))
# print(tuple(g))

创建生成器方法2 return 换成 yield

generator非常强大。如果推算的算法比较复杂,用类似列表生成式的 for 循环无法实现的时候,还可以用函数来实现。

# def Fei(nn):
#     sum1,sum2 = 0,1
#     current = 0               #位置
#     while current < nn:       #if 换成while
#         sum = sum1
#         sum1,sum2 = sum2,sum1 + sum2
#         current += 1
#         yield sum
#
# if __name__ == '__main__':
#
#     # print(Fei(5))                   #<generator object Fei at 0x016A47F0>
#
#     #第一种方法
#     s = Fei(int(input('请输入:')))
# for i in s:
#     print(i)

# def Fei(nn):
#     sum1,sum2 = 0,1
#     current = 0               #位置
#     while current < nn:       #if 换成while
#         sum = sum1
#         sum1,sum2 = sum2,sum1 + sum2
#         current += 1
#         yield sum
#
# if __name__ == '__main__':
#
#     # print(Fei(5))                   #<generator object Fei at 0x016A47F0>
#
#     #第一种方法
#     s = Fei(int(input('请输入:')))
# for i in s:
#     print(i)
# 第二种方法
# while True:
#     try:
#         print(next(s))
#     except StopIteration:
#         break
# 第三种方法
# print(list(s))
# print(tuple(s))

# 扩展send()方法
# a =s.send(None)  #第一个值必须为None 没有为什么
# print(a)
# a =s.send(11)      #后边随便写
# print(a)
# a = s.send(11)
# print(a)
# a = s.send(11)
# print(a)
# a =s.send(11)
# print(a)
# a = s.send(11)
# print(a)
# a = s.send(11)
# print(a)

总结

使用了yield关键字的函数不再是函数,而是生成器。(使用了yield的函数就是生成器)

yield关键字有两点作用:
保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用

可以使用next()函数让生成器从断点处继续执行,即唤醒生成器(函数)

Python3中的生成器可以使用return返回最终运行的返回值,而Python2中的生成器不允许使用return返回一个返回值(即可以使用return从生成器中退出,但return后不能有任何表达式)。

唤醒生成器的三种方试

send()函数 next()函数 __next__方法