返回顶部
首页 > 资讯 > 后端开发 > Python >python:yield总结
  • 488
分享到

python:yield总结

pythonyield 2023-01-31 01:01:56 488人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

资源总结来源于以下各地:1.Http://blog.donews.com/limodou/arcHive/2006/09/04/1028747.aspx2.http://blog.chinaunix.net/uid-26922865-id-

资源总结来源于以下各地:
1.Http://blog.donews.com/limodou/arcHive/2006/09/04/1028747.aspx
2.http://blog.chinaunix.net/uid-26922865-id-3382980.html
3.
4.
5.
可以看到,如果你还是把yield写成语句形式的话,其实还是一个表达式,只是它的值被扔掉了。
那么一个 yield 表达式可以这样写:
x = yield i
y = x + (yield x)
我们可以把 yield 想象成下面的伪代码:
x = yield i ==> put(i); x = wait_and_get()
可以看到,可以理解为先是一个 put(i),这个 i 就是 yield 表达式后面的参数,如果 yield 没有参数,则表示 None。它表示将 i 放到一个全局缓冲区中,相当于返回了一个值。
看一个例子:
>>> def g():
  print 'step 1'
  x = yield 'hello'
  print 'step 2','x = ',x
  y = 5 + (yield x)
  print 'step 3','y=',y

  
>>> f = g()
>>> f.next()
step 1
'hello'
>>>
当我们执行 next() 时,代码执行到 x = yield ‘hello’ 就停住了,并且返回了 yield 后面的 ‘hello’。如果我们把上面的程序替换成伪代码看一看是什么样子:
def g():
        print ’step 1′
        put(‘hello’)        #x = yield ‘hello’
        x = wait_and get()
        print ’stpe 2′, ’x=’, x
        put(x)
        y = 5 + wait_and_get()
        print ’step 3′, ‘y=’, y
可以从伪代码看出,第一次调用 next() 时,先返回一个 ‘hello’, 然后程序挂起在 x = wait_and_get() 上,与我们执行的结果相同。
让我们继续:
>>> f.send(5)
step 2 x= 5
5

这次我们使用了 send(5) 而不是 next() 了。要注意 next() 在 2.5 中只算是 send(None) 的一种表现方式。正如伪代码演示的,send()一个值,先是激活 wait_and_get() ,并且通过它返回 send(5) 的参数5,于是 x 的值是 5,然后打印 ’step 2′,再返回 x 的值5,然后程序挂起在 y = 5 + wait_and_get() 上,与运行结果一致。
如果我们继续:
>>> f.send(2)
step 3 y= 7
Traceback (most recent call last):
    File "<pyshell#13>", line 1, in <module>
        f.send(2)
StopIteration

可以看到先是激活 wait_and_get(),并且通过它返回 send(2) 的参数 2,因此 y 的值是 7,然后执行下面的打印语句,但因为后面没有下一个 yield 语句了,因此程序无法挂起,于是就抛出异常来。
从上面的伪代码的示例和运行结果的分析,我想你应该对 yield 比较清楚了。还有一些要注意的:
  • next()相当于send(None)
  • yield后面没有参数表示返回为None
在文档中有几句话很重要:
意思是说,第一次调用时要么使用 next() ,要么使用 send(None) ,不能使用 send() 来发送一个非 None 的值,原因就是第一次没有一个 yield 表达式来接受这个值。如果你转为伪代码就很好理解。以上例来说明,转换后第一句是一个 put() 而不是wait_and_get(),因此第一次执行只能返回,而不能接受数据。如果你真的发送了一个非 None 的值,会引发一个 TypeError 的异常,让我们试一试:
>>> f = g()
>>> f.send(5)

Traceback (most recent call last):
    File "<pyshell#15>", line 1, in <module>
        f.send(5)
TypeError: can’t send non-None value to a just-started generator
看到了吧,果然出错了。
3. 增加了 throw() 方法,可以用来从 generator 内部来引发异常,从而控制 generator 的执行。试验一下:
>>> f = g()
>>> f.send(None)
step 1
‘hello’
>>> f.throw(GeneratorExit)
Traceback (most recent call last):
    File "<pyshell#17>", line 1, in <module>
        f.throw(GeneratorExit)
    File "<pyshell#6>", line 3, in g
        x = yield ‘hello’
GeneratorExit
>>> f.send(5)
Traceback (most recent call last):
    File "<pyshell#18>", line 1, in <module>
        f.send(5)
StopIteration

可以看出,第一次执行后,我执行了一个f.throw(GeneratorExit),于是这个异常被引发。如果再次执行f.send(5),可以看出 generator 已经被停止了。GeneratorExit 是新增加的一个异常类,关于它的说明:
A new standard exception is defined, GeneratorExit, inheriting from Exception. A generator should handle this by re-raising it (or just not catching it) or by raising StopIteration.
可以看出,增加它的目的就是让 generator 有机会执行一些退出时的清理工作。这一点在 PEP 342 后面的 thumbnail 的例子中用到了。
4. 增加了 close 方法。它用来关闭一个 generator ,它的伪代码如下(从文档中抄来):
def close(self):
        try:
                self.throw(GeneratorExit)
        except (GeneratorExit, StopIteration):
                pass
        else:
                raise RuntimeError("generator ignored GeneratorExit")
# Other exceptions are not caught

因此可以看出,首先向自身引发一个 GeneratorExit 异常,如果 generator 引发了 GeneratorExit 或 StopIteration 异常,则关闭成功。如果 generator 返回了一个值,则引发 RuntimeError 异常。如果是其它的异常则不作处理,相当于向上层繁殖,由上层代码来处理。关于它的例子在 PEP 342 中的 thumbnail 的例子中也有描述。
还有其它几点变化,不再做更深入的描述。
关于 PEP 342 中的例子也很值得玩味。简单说一些,其实我也些也不是很懂也就是明白个大概其吧。
文档中一共有4个例子,其实是两个例子构成。
1,2两个例子完成了一个 thunmbnail 的处理。第一个例子 consumer 其实是一个 decorator ,它实现了对一个 generator 的封装,主要就是用来调用一次 next() 。为什么,因为这样调一次下一次就可以使用 send() 一个非 None 的值了,这样后面的代码在使用 generator 可以直接使用 send() 非 None 值来处理了。第二个例子完成对一系列的图片的缩略图的处理。这里每个图片的处理做成了一个 generator,对于图片文件的处理又是一个顶层的 generator ,在这个顶层的 generator 来调用每个图片处理的 generator。同时这个例子还实现了当异常退出时的一种保护工作:处理完正在处理的图片,然后退出。
3,4两个例子完成了一个 echo 服务器的演示。3完成了一个调度器,4是在3的基础上将listen处理和Socket联通后的handle处理都转为可调度的 generator ,在调度器中进行调度。同时可以看到 socket 使用的是非阻塞的处理。
通过以上的学习,我深深地感受到 yield 的确很精巧,这一点还是在与 shhgs 语音交流之后才有更深的体会,许多东西可以通过 generator 表现得更优美和精巧,是一个非常值得玩味的东西。以至于 shhgs 感觉到在 2.5 中 yield 比 with 的意义要大。希望大家一同体会。
不过说实在的,yield 的东西的确有些难于理解,要仔细体会才行。

--结束END--

本文标题: python:yield总结

本文链接: https://lsjlt.com/news/184510.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • python:yield总结
    资源总结来源于以下各地:1.http://blog.donews.com/limodou/archive/2006/09/04/1028747.aspx2.http://blog.chinaunix.net/uid-26922865-id-...
    99+
    2023-01-31
    python yield
  • oracle总结
    创建表空间create tablespance 表名datafile ‘’;-- 放在的位置size --设置大小autoextend onnext ; --扩展大小 -- 2删除表空间drop tablespance 表名;...
    99+
    2014-09-13
    oracle总结
  • SSTI---总结
     Laravel Blade是Laravel提供的一个既简单又强大的模板引擎 和其他流行的PHP模板引擎不一样,Blade并不限制你在视图view中使用原生的PHP代码 所有的Blade视图页面都将被编译成原生的PHP代码并缓存起来,除...
    99+
    2023-09-21
    安全
  • MyBatisPlus总结
    目录 MyBatisPlus MP特点 MP框架结构 MP使用准备 导入依赖 springboot整合mybatisplus配置文件 定义好实体类User后编辑mapper接口 @Mapper与@MapperScan("包名")区别 MP基...
    99+
    2023-10-18
    java mysql spring
  • python 总结
    一.列表 1.extend(列表独有功能) 循环添加到一个列表中 a.有列表users = ['张三',‘李四]   people = ['小明,王五'] users.extend(people)   # 在users中添加 p...
    99+
    2023-01-31
    python
  • 总结--3
    主线程创建的时候会默认创建Looper、HandlerThread则是内置Looper,除此之外其他的线程创建时是不会创建Looper的,需手动创健线程自己的Looper。子线程更新主线程创建的控件引发的错误:Only the origin...
    99+
    2023-01-31
  • CSS3总结
      一、选择器 1.通用选择器 E~F:E后边所有和E同级的F 2.属性选择器 E[att^=’val’]:att属性中以val开头的 E[att$=’val’]:以val结尾的 E[att*=’val’]含有val的选择器 3.伪类选...
    99+
    2023-01-31
  • 【Pandas总结】第五节 Pandas 数据查询方法总结_df.loc()总结
    文章目录 一、写在前面二、查询方法:`df.loc()`2.1 查询单个值2.2 查询列表对应的值2.3 查询区间内的结果2.4 条件查询2.5 按照函数要求查询 三、写在最后 ...
    99+
    2023-09-26
    pandas python 数据分析
  • Mysql锁总结
    数据库锁设计的初衷是处理并发问题。作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则。而锁就是用来 实现这些访问规则的重要数据结构 根据加锁的范围,MySQL 里面的锁大致可以分成全局锁、表级锁和行锁三类 全局锁...
    99+
    2014-11-05
    Mysql锁总结
  • Handler_read_*的总结
    优化SQL,只懂执行计划?不行滴! 在分析一个SQL的性能好坏时,除了执行计划,另外一个常看的指标是"Handler_read_*"相关变量。 Handler_read_key Handler_read...
    99+
    2021-03-16
    Handler_read_*的总结
  • Oracle锁总结
    《oracle的锁》在数据库中必须要了解的几点:1、事务是数据库的核心,他们是好东西2、应该延迟到适当的时刻才提交。不要太快提交,以避免对系统带来压力,这是因为,即使事务很长或很大,也一般不会对系统造成压力...
    99+
    2024-04-02
  • REF CURSOR 总结
    REF 游标:REF游标又称为动态游标,在运行时使不同的语句与之关联,动态关联结果集的临时对象,即在运行的时候动态决定执行查询。REF游标可以使用游标变量。游标变量:游标变量是一种引用REF游标类型的变量,...
    99+
    2024-04-02
  • 【JAVA】CAS总结
    什么是CAS CAS的全称为Compare-And-Swap,直译就是对比交换。是一条CPU的原子指令,其作用是让CPU先进行比较两个值是否相等,然后原子地更新某个位置的值,其实现方式是基于硬件平台的...
    99+
    2023-09-24
    java jvm 开发语言
  • 【MySQL】总结中
    什么是MySQL MySQL是一个数据库软件,是一个"客户端-服务器"结构的软件。 客户端(Client):主动发起请求的一方。客户端给服务器发起的数据,称为请求(Request) 服务器(Server):被动接收请求的一方。服务器给客户端...
    99+
    2023-09-09
    mysql oracle 数据库
  • Android TabLayout总结
    文章目录 Android TabLayout总结基本使用添加图标、隐藏下划线自定义下划线、添加分割线设置角标圆角样式自定义View+Lottile代码下载 Android TabLay...
    99+
    2023-09-04
    android TabLayout
  • MySQL大总结
    目录 一、MySQL数据库基础 1,数据库的操作 1.1、显示当前数据库 1.2 、创建数据库 1.3、使用数据库 1.4、删除数据库 2、常用数据类型 2.1、数值类型 2.2、字符串类型  2.3、日期类型 3、表的操作 3.1、创建表...
    99+
    2023-09-04
    mysql 面试 java
  • PYthon signal总结
    预设信号处理函数 signal包的核心是使用signal.signal()函数来预设(register)信号处理函数,如下所示: singnal.signal(signalnum, handler) signalnum为某个...
    99+
    2023-01-31
    PYthon signal
  • Python-socket总结
    socket是什么什么是socket所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。说白了就是一种通信机制。列入你和移动客服咨询问题时,会有一个客服...
    99+
    2023-01-31
    Python socket
  • Python import 【总结】
    Python import总结可能网上很多文章或博客都没解释清楚,作者自己也苦心于Python的import。至此,把自己的总结的分享给大家,本文不做基础讲解,仅说明疑惑的地方。新版本的Pycharm 2017.1.1,对自己定义的模块都有...
    99+
    2023-01-31
    Python import
  • MySQL总结-3
      1、连接  mysql -u username -ppassword -P 3306 -D database -hip 2、列显示:"\G" mysql> select * from HUMMOCK_BLACK_LIST...
    99+
    2023-01-31
    MySQL
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作