位置: 编程技术 - 正文

Python 3中的yield from语法详解(python yield from 用法)

编辑:rootadmin

推荐整理分享Python 3中的yield from语法详解(python yield from 用法),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:pythin yield,pythonyield详解,python中yield函数怎么用,python中yield函数怎么用,python中yield函数怎么用,python3 yield用法,python yieid,python里面的yield,内容如对您有帮助,希望把文章链接给更多的朋友!

前言

最近在捣鼓Autobahn,它有给出个例子是基于asyncio 的,想着说放到pypy3上跑跑看竟然就……失败了。 pip install asyncio直接报invalid syntax,粗看还以为2to3处理的时 候有问题——这不能怪我,好~多package都是用2写了然后转成3的——结果发 现asyncio本来就只支持3.3+的版本,才又回头看代码,赫然发现一句 yield from;yield我知道,但是yield from是神马?

PEP-

好吧这个标题是我google出来的,yield from的前世今生都在 这个PEP里面,总之大意是原本的yield语句只能将CPU控制权 还给直接调用者,当你想要将一个generator或者coroutine里带有 yield语句的逻辑重构到另一个generator(原文是subgenerator) 里的时候,会非常麻烦,因为外面的generator要负责为里面的 generator做消息传递;所以某人有个想法是让python把消息传递 封装起来,使其对程序猿透明,于是就有了yield from。

PEP-规定了yield from的语义,或者说嵌套的generator应该 有的行为模式。

假设A函数中有这样一个语句

B()返回的是一个可迭代(iterable)的对象b,那么A()会返回一个 generator——照我们的命名规范,名字叫a——那么:

b迭代产生的每个值都直接传递给a的调用者。 所有通过send方法发送到a的值都被直接传递给b. 如果发送的 值是None,则调用b的__next__()方法,否则调用b的send 方法。如果对b的方法调用产生StopIteration异常,a会继续 执行yield from后面的语句,而其他异常则会传播到a中,导 致a在执行yield from的时候抛出异常。 如果有除GeneratorExit以外的异常被throw到a中的话,该异常 会被直接throw到b中。如果b的throw方法抛出StopIteration, a会继续执行;其他异常则会导致a也抛出异常。 如果一个GeneratorExit异常被throw到a中,或者a的close 方法被调用了,并且b也有close方法的话,b的close方法也 会被调用。如果b的这个方法抛出了异常,则会导致a也抛出异常。 反之,如果b成功close掉了,a也会抛出异常,但是是特定的 GeneratorExit异常。 a中yield from表达式的求值结果是b迭代结束时抛出的 StopIteration异常的第一个参数。 b中的return <expr>语句实际上会抛出StopIteration(<expr>) 异常,所以b中return的值会成为a中yield from表达式的返回值。

为神马会有这么多要求?因为generator这种东西的行为在加入throw 方法之后变得非常复杂,特别是几个generator在一起的情况,需要 类似进程管理的元语对其进行操作。上面的所有要求都是为了统一 generator原本就复杂的行为,自然简单不下来啦。

我承认我一下没看明白PEP的作者到底想说什么,于是动手“重构” 一遍大概会有点帮助。

一个没用的例子

Python 3中的yield from语法详解(python yield from 用法)

说没用是因为你大概不会真的想把程序写成这样,但是……反正能说明 问题就够了。

设想有这样一个generator函数:

这个函数生成的generator将从send方法接收到的值累加到局部 变量total中,并且在收到BreakOut异常时停止迭代;至于另外 一个SwitchSign异常应该不难理解,这里就不剧透了。

从代码上看,由inner()函数得到的generator通过send接收用于 运算的数据,同时通过throw方法接受外部代码的控制以执行不同 的代码分支,目前为止都很清晰。

接下来因为需求有变动,我们需要在inner()这段代码的前后分别加 入初始化和清理现场的代码。鉴于我认为“没坏的代码就不要动”,我 决定让inner()维持现状,然后再写一个outer() ,把添加的代码放在 outer()里,并提供与inner()一样的操作接口。由于inner()利用了 generator的若干特性,所以outer()也必须做到这五件事情:

outer()必须生成一个generator; 在每一步的迭代中,outer()要帮助inner()返回迭代值; 在每一步的迭代中,outer()要帮助inner()接收外部发送的数据; 在每一步的迭代中,outer()要处理inner()接收和抛出所有异常; 在outer()被close的时候,inner()也要被正确地close掉。

根据上面的要求,在只有yield的世界里,outer()可能是长这样的:

WTF,这段代码比inner()本身还要长,而且还没处理close操作。

现在我们来试试外星科技:

除了完全符合上面的要求外,这四行代码打印出来的时候还能省点纸。

我们可以在outer1()和outer2()上分别测试 数据 以及 异常 的传递,不难发现这两个generator的行为基本上是一致的。既然如此, 外星科技当然在大多数情况下是首选。

对generator和coroutine的疑问

从以前接触到Python下的coroutine就觉得它怪怪的,我能看清它们的 行为模式,但是并不明白为什么要使用这种模式,generator和 coroutine具有一样的对外接口,是generator造就了coroutine呢,还 是coroutine造就了generator?最让我百思不得其解的是,Python下 的coroutine将“消息传递”和“调度”这两种操作绑在一个yield 上——即便有了yield from,这个状况还是没变过——我看不出这样做 的必要性。如果一开始就从语法层面将这两种语义分开,并且为 generator和coroutine分别设计一套接口,coroutine的概念大概也会 容易理解一些。

总结

标签: python yield from 用法

本文链接地址:https://www.jiuchutong.com/biancheng/381419.html 转载请保留说明!

上一篇:Python中的字符串操作和编码Unicode详解(python中的字符串必须写在一对双引号中)

下一篇:python 开发的三种运行模式详细介绍(python开发的程序)

  • 企业交的增值税怎么做账
  • 记账凭证核算形式是会计核算中最基本的核算形式
  • 企业法人如何网上实名认证
  • 报关单保费000/0.1/1
  • 收到上月保险赔偿款分录
  • 季中转一般纳税人申报步骤
  • 签订合同后付款
  • 委托开发票的证明怎么写
  • 房产折旧计算方法 举例
  • 免税即征即退先征后退
  • 会计凭证的填制与审核过程
  • 发票进项转出账务怎么做
  • 被开除了怎么办理手续
  • 子公司向母公司借款对合并报表的影响
  • 出口退税金额和进项税额不一致
  • 3%税率是一般纳税人还是小规模
  • 房贷利息在哪里能看到
  • 企业赠送客户产品如何账务处理
  • 什么样的企业有核心能力
  • 坏账准备属于哪个会计科
  • 运输费计入什么会计分录
  • 超市购物卡返点一般是几个点
  • osXYosemite怎么更新
  • ios9.3.5如何越狱
  • 查补增值税的会计处理
  • mac osx10.11
  • php 智能家居
  • 无法偿还应付账款账务处理
  • PHP:imagecolortransparent()的用法_GD库图像处理函数
  • php使用while循环计算1到100的和
  • laravel 5.4中实现无限级分类的方法示例
  • php访问数据库的方式
  • 哪一款macbook
  • 会员卡怎样批量生成
  • 附加税申报核心内容
  • 公司旅游费会计分录
  • 外贸客户付款方式
  • 普通发票该可以抵扣吗
  • 生产部门使用的无形资产摊销
  • 年报资金数额是什么意思
  • 企业财务费用为负好不好
  • sqlserver日期加减月份
  • 民间非营利组织会计科目
  • 小规模纳税人是查账征收还是核定征收
  • 分期付款服务费是什么
  • 企业库存现金的限额是
  • 通货紧缩的影响简答题
  • 包装物押金怎么计算
  • 预收账款和预付账款科目都是资产类科目
  • 员工缴纳工伤保险怎么赔偿
  • 给员工缴纳的雇工保险
  • 经营杠杆系数的经济含义
  • 开出银行承兑汇票一张用于支付材料采购款
  • 农产品如何进入批发市场
  • 有净残值的固定资产怎么计提折旧
  • 股东借款转为资本公积的决议
  • 采购方退货的会计分录
  • 如果找国外客户
  • 给员工家人报销会计分录
  • 冲红的发票抵扣联要放在凭证里吗
  • 纳税人和负税人区别通俗易懂
  • 光盘安装系统怎么操作
  • wmpdmc.exe是什么意思
  • 家庭版的海鲜大杂烩
  • linux常用的几种压缩工具
  • win7如何删除无法删除的文件
  • linux纯文本浏览器
  • windows休眠文件
  • js 加减
  • jQuery实现仿新浪微博浮动的消息提示框(可智能定位)
  • fragment的context
  • bat文件加密bat解密脚本
  • delect删除
  • 浅谈python装饰器探究与参数的领取
  • vue组件精讲
  • unity 3渲2
  • 山东国地税合并6月挂牌
  • 财税公司经营范围介绍
  • 惠济区第五中学怎么样
  • 国外工资个人所得税
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设