关于Python中的yield

在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor)。python

1、迭代器(iterator)函数

在Python中,for循环能够用于Python中的任何类型,包括列表、元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器工具

迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引起StopIteration。任何这类的对象在Python中均可以用for循环或其余遍历工具迭代,迭代工具内部会在每次迭代时调用next方法,而且捕捉StopIteration异常来肯定什么时候离开。spa

使用迭代器一个显而易见的好处就是:每次只从对象中读取一条数据,不会形成内存的过大开销。code

好比要逐行读取一个文件的内容,利用readlines()方法,咱们能够这么写:orm

1
2
 line  .:
     line

这样虽然能够工做,但不是最好的方法。由于他其实是把文件一次加载到内存中,而后逐行打印。当文件很大时,这个方法的内存开销就很大了。对象

利用file的迭代器,咱们能够这样写:接口

1
2
 line  :   
     line

这是最简单也是运行速度最快的写法,他并没显式的读取文件,而是利用迭代器每次读取下一行。内存

2、生成器(constructor)ci

生成器函数在Python中与迭代器协议的概念联系在一块儿。简而言之,包含yield语句的函数会被特意编译成生成器。当函数被调用时,他们返回一个生成器对象,这个对象支持迭代器接口。函数也许会有个return语句,但它的做用是用来yield产生值的。

不像通常的函数会生成值后退出,生成器函数在生成值后会自动挂起并暂停他们的执行和状态,他的本地变量将保存状态信息,这些信息在函数恢复时将再度有效

1
2
3
4
5
6
7
8
  gn:
...      i  n:
...              i 
...
  i  g:
...      i,,
...
 :  :  :  :  :

要了解他的运行原理,咱们来用next方法看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 t = g
 t.

 t.

 t.

 t.

 t.

 t.
Traceback most recent call last:
  File , line ,  module

在运行完5次next以后,生成器抛出了一个StopIteration异常,迭代终止。
再来看一个yield的例子,用生成器生成一个Fibonacci数列:

1
2
3
4
5
6
7
8
9
10
 fab:
    a,b = ,
     a  :
         a
        a, b = b, a+b
 
  i  fab:
...      i,,
...
 ,  ,  ,  ,  ,  ,  ,  ,

看到这里应该就能理解生成器那个很抽象的概念了吧~~

相关文章
相关标签/搜索