1.

A generator: provide a kind of function that can return an intermediate result ("the next value") to its caller, but maintaining the function's local state so that the function can be resumed again right where it left off.

A very simple example:

def fib():
a, b = 0, 1
while 1:
yield b
a, b = b, a+b

When fib() is first invoked, it sets a to 0 and b to 1, then yields b back to its caller. The caller sees 1. When fib is resumed, from its point of view the yield statement is really the same as, say, a print statement: fib continues after the yield with all local state intact. a and b then become 1 and 1, and fib loops back to the yield, yielding 1 to its invoker. And so on. From fib's point of view it's just delivering a sequence of results. But from its caller's point of view, the fib invocation is an iterable object that can be resumed at will.

The yield statement may only be used inside functions. A function that contains a yield statement is called a generator function.

When a generator function is called, the actual arguments are bound to function-local formal argument names in the usual way, but no code in the body of the function is executed. Instead a generator-iterator object is returned; this conforms to the iterator protocol, so in particular can be used in for-loops in a natural way.

Each time the .next() method of a generator-iterator is invoked, the code in the body of the generator-function is executed until a yield or return statement (see below) is encountered, or until the end of the body is reached.

If a yield statement is encountered, the state of the function is frozen, and the value of expression_list is returned to .next()'s caller. By "frozen" we mean that all local state is retained, including the current bindings of local variables, the instruction pointer, and the internal evaluation stack: enough information is saved so that the next time .next() is invoked, the function can proceed exactly as if the yield statement were just another external call.

Note that an expression_list is not allowed on return statements in the body of a generator.

When a return statement is encountered, control proceeds as in any function return, executing the appropriate finally clauses (if any exist). Then a StopIteration exception is raised, signalling that the iterator is exhausted. A StopIteration exception is also raised if control flows off the end of the generator without an explicit return.

2: send

A new method for generator-iterators is proposed, called send(). It takes exactly one argument, which is the value that should be sent in to the generator. Calling send(None) is exactly equivalent to calling a generator's next() method. Calling send() with any other value is the same, except that the value produced by the generator's current yield expression will be different.

Because generator-iterators begin execution at the top of the generator's function body, there is no yield expression to receive a value when the generator has just been created. Therefore, calling send() with a non-None argument is prohibited when the generator iterator has just started, and a TypeError is raised if this occurs (presumably due to a logic error of some kind). Thus, before you can communicate with a coroutine you must first call next() or send(None) to advance its execution to the first yield expression.

The yield-statement will be allowed to be used on the right-hand side of an assignment; in that case it is referred to as yield-expression. The value of this yield-expression is None unless send() was called with a non-None argument; see below.

Note that a yield-statement or yield-expression without an expression is now legal. This makes sense: when the information flow in the next() call is reversed, it should be possible to yield without passing an explicit value (yield is of course equivalent to yield None).

When send(value) is called, the yield-expression that it resumes will return the passed-in value. When next() is called, the resumed yield-expression will return None. If the yield-expression is a yield-statement, this returned value is ignored, similar to ignoring the value returned by a function call used as a statement.

3: Exceptions and Cleanup

throw(type, value=None, traceback=None)

g.throw(type, value, traceback) causes the specified exception to be thrown at the point where the generator g is currently suspended (i.e. at a yield-statement, or at the start of its function body if next() has not been called yet). If the generator catches the exception and yields another value, that is the return value of g.throw(). If it doesn't catch the exception, the throw() appears to raise the same exception passed it (it falls through). If the generator raises another exception (this includes the StopIteration produced when it returns) that exception is raised by the throw() call. In summary, throw() behaves like next() or send(), except it raises an exception at the suspension point. If the generator is already in the closed state, throw() just raises the exception it was passed without executing any of the generator's code.

The effect of raising the exception is exactly as if the statement:  raise type, value, traceback

was executed at the suspension point. The type argument must not be None, and the type and value must be compatible.

g.close() is defined by the following pseudo-code:

def close(self):
try:
self.throw(GeneratorExit)
except (GeneratorExit, StopIteration):
pass
else:
raise RuntimeError("generator ignored GeneratorExit")
# Other exceptions are not caught

https://www.python.org/dev/peps/pep-0342/

https://www.python.org/dev/peps/pep-0255/

Python2 生成器 简介的更多相关文章

  1. Python3.x:生成器简介

    Python3.x:生成器简介 概念 任何使用yield的函数都称之为生成器:使用yield,可以让函数生成一个序列,该函数返回的对象类型是"generator",通过该对象连续调 ...

  2. 【翻译】ES6生成器简介

    原文地址:http://davidwalsh.name/es6-generators ES6生成器全部文章: The Basics Of ES6 Generators Diving Deeper Wi ...

  3. Python基础之生成器

    1.生成器简介 首先请确信,生成器就是一种迭代器.生成器拥有next方法并且行为与迭代器完全相同,这意味着生成器也可以用于Python的for循环中.另外,对于生成器的特殊语法支持使得编写一个生成器比 ...

  4. c#分布式ID生成器

    c#分布式ID生成器   简介 这个是根据twitter的snowflake来写的.这里有中文的介绍. 如上图所示,一个64位ID,除了最左边的符号位不用(固定为0,以保证生成的ID都是正数),还剩余 ...

  5. python学习日记(迭代器、生成器)-乱七八糟

    迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退 ...

  6. 【awesome-dotnet-core-learning】(3)-Bogus-假数据生成器

    [awesome-dotnet-core-learning](3)-Bogus-假数据生成器 简介 Bogus一个简单而强大的假数据生成器,用于C#,F#和VB.NET.从著名的faker.js移植过 ...

  7. 【scikit-learn】06:make_blobs聚类数据生成器

      版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/kevinelstri/article/ ...

  8. PythonI/O进阶学习笔记_9.python的生成器

     content: 1. 什么是生成器 2. 生成器的实现 3. 生成器的应用   一.生成器简介 1.什么是生成器     在 Python 中,使用了 yield 的函数被称为生成器(genera ...

  9. 生成器和迭代器_python

    一.生成器简介(generator) 在进行较大数据的存储,如果直接存储在列表之中,则会可能造成内存的不够与速度的减慢,因为列表创建完是立即创建并存在的,而在python中生成器(generator) ...

随机推荐

  1. PHP数组循环遍历的四种方式

     1.使用for循环遍历数组     conut($arr);用于统计数组元素的个数.     for循环只能用于遍历,纯索引数组!!!!     如果存在关联数组,count统计时会统计两种数组的总 ...

  2. Webpack构建前端项目

    前言 公司据说要搞前后端分离,趁这两天项目完成的差不多,抓紧时间学习一下前端知识 现在流行前端项目工程化,那么第一个问题就是如何创建工程(项目),第一次玩webpack 通过 NPM 创建项目 # 创 ...

  3. hdu1233还是畅通工程

    还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  4. 解释性语言和非解释性语言,GIL锁

    解释性语言:python写的代码就被称为程序,cpu硬件能运行二进制代码指令.demo.py需要经过python解释器编译才做才能执行. 非解释性语言:例如c语言程序,同样需要写代码.demo.c这个 ...

  5. 系统io统计

      $ cat /proc/diskstats sda sda1 sda2 gg- gg- gg- 主号 次号 名称 成功读 合并读 扇区读 读时间   每一列的含义分别为: 第一列为 设备号 (nu ...

  6. 前端(Node.js)(2)-- Node.js开发环境配置

    1.开发环境介绍 1.MEAN Stack 什么是全栈? 负责界面和UI的设计师.负责移动端应用开发的安卓IOS开发工程师.负责服务器端开发的后端程序员.负责数据库开发和管理的数据库工程师.负责服务器 ...

  7. 使用Jedis操作Redis-使用Java语言在客户端操作---String类型

    前提:需要引入Jedis的jar包. /** * 我的redis在Linux虚拟机Centos7中,192.168.222.129是我虚拟机的ip地址. */ private static Jedis ...

  8. springboot中logback打印日志(转)

    springboot对logback的支持是非常好的,不需要任何配置,只需要在resource下加logback.xml就可以实现功能 直接贴代码: <?xml version="1. ...

  9. BootStrap 栅格化换行问题

    bootstrap 3的栅格系统有时会出现错位情况,原因是上一行的元素高度不一,导致元素float错误. 解决方法 使用栅格系统的时候,应该在每一行都使用row单独包裹起来,不要直接在一行中连续加入c ...

  10. C++ operator new和new operator的区别

    new operator 当你写这种代码: string *ps = new string("Memory Management"); 你使用的new是new  operator. ...