生成器详解
2017-04-23 19:17
113 查看
可迭代对象(iterable) 与 迭代器(iterator)
关系如下图:对一个iterable用for … in …进行迭代时,实际是先通过调用iter()方法得到一个iterator,假设叫做X。然后循环地调用X的next()方法取得每一次的值,直到iterator为空,返回的StopIteration作为循环结束的标志。for … in … 会自动处理StopIteration异常,从而避免了抛出异常而使程序中断。
生成器
生成器,就是带有yield的函数。包含生成器函数和生成器表达式(形如(elem for elem in [1, 2, 3])的表达式)生成器函数(generator function)的返回值是生成器、迭代器(generator iterator)
生成器表达式(generator expression)的返回值是迭代器(iterator)
示例代码如下:
>>> a = (elem for elem in [1, 2, 3]) >>> a <generator object <genexpr> at 0x7f0d23888048> >>> def fib(): ... a, b = 0, 1 ... while True: ... yield b ... a, b = b, a + b ... >>> fib <function fib at 0x7f0d238796a8> >>> b = fib() <generator object fib at 0x7f0d20bbfea0>
综上:生成器(generator)就是迭代器(iterator)的一种,以更优雅的方式实现的iterator,而且完全可以像使用iterator一样使用generator。当然除了定义,定义一个iterator,你需要分别实现_ _ iter _ _ ()方法和 _ _ next_ _()方法,但generator只需要一个小小的yield
生成器的调用方法:
示例代码:
>>> def gen(): ... while True: ... s = yield ... print(s) ... >>> g = gen() >>> g.send("kissg") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can't send non-None value to a just-started generator >>> next(g) >>> g.send("kissg") kissg
从上述例子可以看出,generator 其实有2种调用方法(恢复执行),即通过send(value)方法将value作为yield表达式的当前值。你可以用该值再对其他变量进行赋值。当我们调用send(value)方法时,generator正由于yield的缘故被暂停了。此时,send(value)方法传入的值作为yield表达式的值,函数中又将该值赋给了变量s,然后print函数打印s,循环再遇到yield,暂停返回。
调用send(value)时要注意,要确保 generator 是在yield处被暂停了,如此才能向yield表达式传值,否则将会报错(如上所示),可通过next()方法或send(None)使generator执行到yield。
再来看一段yield更复杂的用法,或许能加深你对generator的next()与send(value)的理解。
>>> def echo(value=None): ... while 1: ... value = (yield value) ... print("The value is", value) ... if value: ... value += 1 ... >>> g = echo(1) >>> next(g) 1 >>> g.send(2) The value is 2 3 >>> g.send(5) The value is 5 6 >>> next(g) The value is None
小结
可迭代对象(Iterable)是实现了iter()方法的对象,通过调用iter()方法可以获得一个迭代器(Iterator)。
迭代器(Iterator)是实现了iter()和next()的对象。
for … in …的迭代,实际是将可迭代对象转换成迭代器,再重复调用next()方法实现的。
生成器(generator)是一个特殊的迭代器,它的实现更简单优雅。
yield是生成器实现next()方法的关键。它作为生成器执行的暂停恢复点,可以对yield表达式进行赋值,也可以将yield表达式的值返回。
参考文档:http://kissg.me/2016/04/09/python-generator-yield/
相关文章推荐
- 深入本机影像生成器(Ngen.exe)工具使用方法详解
- javadoc - Java API 文档生成器详解 转贴
- JavaScript中的迭代器和生成器详解
- 举例详解Python中yield生成器的用法
- 详解Python3中yield生成器的用法
- 举例详解Python中yield生成器的用法
- 详解Python的迭代器、生成器以及相关的itertools包
- Python函数式编程指南(四):生成器详解
- python的迭代器与生成器实例详解
- hibernate中id生成器详解
- C++ - 随机数生成器(random-number generator) 的 详解 及 代码
- python的迭代器与生成器实例详解
- JavaScript中的迭代器和生成器详解
- C++ - 随机数生成器(random-number generator) 的 详解 及 代码
- hibernate中id生成器详解
- Hibernate中映射详解(一)--基本映射及主键生成器
- Hibernate中映射详解(一)--基本映射及主键生成器 .
- Python生成器(Generator)详解
- 详解Python3中yield生成器的用法
- ES6学习——生成器(Generators):原型继承关系详解