Python中一边计算一边输出的机制,称之为 生成器 Generator

换句话说,生成器是一个类对象,具备 send函数

可以替代一次性计算过度的函数语句

 

生成器 是可被迭代的类型,并且可以被用作next函数,所以生成器一定是迭代器。

 

迭代器 和 可迭代 的 区别:

迭代器 是 可迭代的,可迭代的不一定是迭代器,可迭代的可以通过iter函数转换为迭代器。迭代器的标志之一是可以被作用于next函数。可迭代的标识之一是可以被用于for循环。

自定义数据类型,希望是可迭代的话,需要继承迭代器类型,改写next函数;或者支持__iter__函数转换为迭代器类型。

 

生成器相比迭代器,多支持了一个send方法,支持给生成器传入指定参数,来干涉下一步生成(迭代)。

生成器的next调用相当于 send(None)调用,就是不传入参数的生成(迭代)。

另外还多一个close()调用,结束此次生成过程。

实现生成器的一种方法是把列表生成式的[]变成()运算符就得到了一个生成器,实现自定义生成器类型的另外一种写法 是 使用yield关键字。

函数中yield的使用场景可能是 变量x = yield 表达式y

对应生成器的执行规则是,每次调用send函数,执行完表达式y,send的返回是表达式结果,下次调用send时,将send的参数传给x,然后启动直到下一次yield或者结束了就是StopIteration异常抛出。

但是对于生成器来说,首次生成(迭代)必须是send(None)调用,等价于next()调用。

 

为什么生成器生成器的首次启动 需要 Send(None)呢,我就是传参进去会有啥问题非要抛出异常吗?

因为从生成器的yield执行流程来看,它第一次生成的时候,又叫做启动生成器,是不没法接收传入参数的,所以可能是为了强调这一点,所以强制了首次生成的Send必须传None吧。