生成器函数的工作原理
只要 Python 函数的定义体中有 yield 关键字, 该函数就是生成器函数。 调用生成器函数时, 会返回一个生成器对象。 也就是说, 生成器函数是生成器工厂。

调用生成器函数返回生成器; 生成器产出或生成值.

构建可迭代的对象和迭代器时经常会出现错误, 原因是混淆了二者。

要知道,可迭代的对象必须能从同一个可迭代的实例中获取多个独立的迭代器, 而且各个迭代器要能维护自身的内部状态,可迭代的对象有个 __iter__ 方法, 每次都实例化一个新的迭代器,而迭代器要实现 __next__ 方法, 返回单个元素, 此外还要实现__iter__ 方法, 返回迭代器本身。

因此, 迭代器可以迭代, 但是可迭代的对象不是迭代器。

可迭代的对象一定不能是自身的迭代器。 也就是说, 可迭代的对象必须实现 __iter__ 方法, 但不能实现 __next__ 方法。另一方面, 迭代器应该一直可以迭代。 迭代器的 __iter__ 方法应该返回自身。

比如字符串“hello world”是可迭代对象,对字符串调用iter方法(it = iter("hello world"))会返回一个迭代器 it, 迭代器it有__iter__方法和__next__方法,__next__方法放回下一个元素,__iter__方法返回迭代器本身。

虽然生成器函数看起来像函数, 可是我们不能通过简单的函数调用把职责委托给另一个生成器函数.Python 新引入的 yield from 句法允许生成器或协程把工作委托给第三方完成。

从句法上看, 协程与生成器类似, 都是定义体中包含 yield 关键字的函数。 可是, 在协程中, yield 通常出现在表达式的右边( 例如, datum = yield) , 可以产出值, 也可以不产出——如果 yield关键字后面没有表达式, 那么生成器产出 None

  协程使用生成器函数定义: 定义体中有 yield 关键字。

  yield 在表达式中使用; 如果协程只需从客户那里接收数据, 那么产出的值是 None——这个值是隐式指定的, 因为 yield 关键字右边没有表达式

  协程需要预激(next(gen) before gen.send(data))

在协程中, yield 碰巧( 通常) 出现在赋值语句的右手边, 因为 yield 用于接收客户传给 .send() 方法的参数。

仅当协程处于暂停状态的时候,才能使用send()发送值,如果协程还没有激活,则需要使用next(gen)进行激活(让协程向前执行到第一个 yield 表达式, 准备好作为活跃的协程使用),或者gen.send(None).

协程获取值的方法:

  1. 在协程中使用return,协程终止后,捕获StopIteration,StopIteration.value为return的值

  2. 使用yield from,对yield from 结构来说,解释器不仅会捕获 StopIteration 异常, 还会把 value 属性的值变成 yield from 表达式的值。yield from 结构会在内部自动捕获StopIteration 异常,这种处理方式与 for 循环处理 StopIteration异常的方式一样: 循环机制使用用户易于理解的方式处理异常。

与 .__next__() 方法一样, .send() 方法致使生成器前进到下一个yield 语句。 不过, .send() 方法还允许使用生成器的客户把数据发给自己, 即不管传给 .send() 方法什么参数, 那个参数都会成为生成器函数定义体中对应的 yield 表达式的值。 也就是说, .send() 方法允
许在客户代码和生成器之间双向交换数据。 而 .__next__() 方法只允许客户从生成器中获取数据。改变了生成器的本性: 像这样使用的话,生成器就变身为协程

yield from 结构的作用:

  替代产出值的嵌套 for 循环

  yield from 的主要功能是打开双向通道, 把最外层的调用方与最内层的子生成器连接起来, 这样二者可以直接发送和产出值, 还可以直接传入异常, 而不用在位于中间的协程中添加大量处理异常的样板代码。 有了这个结构, 协程可以通过以前不可能的方式委托职责。

因为委派生成器相当于管道, 所以可以把任意数量个委派生成器连接在一起: 一个委派生成器使用 yield from 调用一个子生成器, 而那个子生成器本身也是委派生成器, 使用 yield from 调用另一个子生成器, 以此类推。 最终, 这个链条要以一个只使用 yield表达式的简单生成器结束; 不过, 也能以任何可迭代的对象结束。

两种方法能避免阻塞型调用中止整个应用程序的进程:
  在单独的线程中运行各个阻塞型操作
  把每个阻塞型操作转换成非阻塞的异步调用使用

from:《Fluent Python》

python 可迭代对象与迭代器的更多相关文章

  1. Python可迭代对象、迭代器和生成器

    Python可迭代对象.迭代器和生成器 python 函数 表达式 序列 count utf-8 云栖征文 python可迭代对象 python迭代器 python生成器 摘要: 8.1 可迭代对象( ...

  2. python可迭代对象和迭代器和生成器

    可迭代对象 刚开始我认为这两者是等同的,但后来发现并不是这样:下面直接抛出结论: )可迭代对象包含迭代器. )如果一个对象拥有__iter__方法,其是可迭代对象:如果一个对象拥有next方法,其是迭 ...

  3. Python -- 可迭代对象和迭代器

    5.9 可迭代对象 可迭代对象: str , list , tuple , set , dict , range 1.在Python中,但凡内部有__iter__方法的对象,都是可迭代对象 2.查看对 ...

  4. 详解python可迭代对象、迭代器和生成器

    可迭代对象 什么是可迭代对象?顾名思义就是可以迭代的一个对象,再通俗点就是可以被for循环遍历的对象,如常用的list.str等数据类型.我们可以使用isinstance来判断这个数据是否是可迭代对象 ...

  5. python 可迭代对象,迭代器,生成器的区别及使用

    可迭代对象 可迭代对象类型:list,dict,tuple,str,set,deque等 如何判断一个对象是否是可迭代对象,可以通过dir()方法看它里面有没有__iter__方法,如果有这个方法就是 ...

  6. python 可迭代对象,迭代器和生成器,lambda表达式

    分页查找 #5.随意写一个20行以上的文件(divmod) # 运行程序,先将内容读到内存中,用列表存储. # l = [] # 提示:一共有多少页 # 接收用户输入页码,每页5条,仅输出当页的内容 ...

  7. Python可迭代对象和迭代器对象

    可迭代对象iterable: 对象字面意思:Python中一切皆对象.一个实实在在存在的值. 可迭代:更新迭代.迭代是一个重复的过程,每次重复是基于上一次的结果而继续的,每次都有新的内容. 可迭代对象 ...

  8. python(可迭代对象,迭代器,生成器及send方法详解)

    一.可迭代对象 对象必须提供一个__iter__()方法,如果有,那么就是可迭代对象, 像列表,元祖,字典等都是可迭代对象可使用isinstance(obj,Iterable)方法判断 from co ...

  9. python 可迭代对象与迭代器之间的转换

    列表: >>> l = [1, 2, 3, 4] >>> l_iter = iter(l) >>> l_iter <list_iterato ...

随机推荐

  1. C语言强化——链表(1)

    目录 链表的增删(不带头结点) 链表相关面试题 合并两个有序链表 单链表原地逆置 找出链表的倒数第四个节点 找出链表的中间节点 判断单链表是否有环 求链表交点 删除有序单链表中重复的元素 链表按奇数. ...

  2. go中redis使用小结

    最近做了个关于redis的项目,那么就整理下遇到和未遇到的问题 1.redis的简介安装 2.redis的数据结构 3.Redis基本使用 4.Redis的并发 5.Redis的落地 一.redis的 ...

  3. Linux常用命令1-50(持续更新中)

    1:echo $PATH  (打印出PATH变量的值) 不同用户下面的PATH值有可能不一样 echo   有显示打印的意思 $         表示后面的是一个变量的意思 PATH  变量 /usr ...

  4. c#day03

    c#中的随机数 Random random = new Random(); //随机1~200之间的一个数 random.Next(,); //怪兽:防御为10,血量为10 //玩家:随机8~12的攻 ...

  5. MySQL5.7修改默认密码、随机密码

    mysql5.7以后默认生成随机密码,修改root用户密码 1.修改配置参数Linux: /etc/my.cnf Windows:  C:\ProgramData\MySQL\MySQL Server ...

  6. Angular2 入门详解

    AngularJS 2 快速入门 npm是什么?   npm其实是Node.js Package Manager的简称,是Node.js包管理工具(package manager) 安装Node.js ...

  7. Python工程化小结

    对如何写一个工业级的Python项目作一个top-down小结. 一.项目结构 顶层结构: 文件夹: model可以是项目中的自定义类: utils是一些工程工具,比如log,tracker log存 ...

  8. 解决linux更新apt软件源时报出GPG错误

    今天给树莓派换源,爆出N个这错误: W: GPG error: http://mirrors.neusoft.edu.cn/raspbian/raspbian wheezy InRelease: Th ...

  9. CS229 6.11 Neurons Networks implements of self-taught learning

    在machine learning领域,更多的数据往往强于更优秀的算法,然而现实中的情况是一般人无法获取大量的已标注数据,这时候可以通过无监督方法获取大量的未标注数据,自学习( self-taught ...

  10. mysql之完整性约束

    主要内容 not null 与 default unique primary auto_increment foreign key 约束条件作用:用于保证数据的完整性和一致性 主要分为 PRIMARY ...