流畅的python笔记(十六)协程

Python 协程详解 yield item这行代码会产出一个值,提供给next()的调用方;此外还会做出让步,暂停执行生成器,让调用方继续工作,知道需要使用另一个值再调用next()。调用方会从生成器中拉取值。从语法上来看,协程与生成器类似,都是从定义体中包含yield关键字的函数。可是,在协程中,yield通常出现在表达式的右边(如data = yield),可以产出值,也可以不产出:如果yield关键字后面没有表达式,那么生成器产出None。 阅读详情

目录

一、生成器如何进化成协程

二、用作协程的生成器的基本行为

三、使用协程计算移动平均值 

四、预激协程的装饰器

五、终止协程和异常处理

发送哨符值让协程退出

使用throw和close显式把异常发给协程

generator.throw(exc_type[, exc_value[, traceback]])

generator.close()

使用close和throw控制协程例子

六、让协程返回值

七、使用yield from

八、yield from的意义

yield from六点行为

yield from与异常处理


一、生成器如何进化成协程

python2.5以后,yield关键字可以在表达式中使用,而且生成器API增加了.send(value)方法。生成器的调用方可以使用.send()方法发送数据,发送的数据会成为生成器函数中yield表达式的值。因此生成器可以作为协程使用。协程是指一个过程,这个过程与调用方协作,产出由调用方提供的值。

        除了.send()方法外,还添加了.throw()和.close()方法:

  • send()方法,调用方使用send方法发送数据,该数据会成为生成器函数中yield表达式的值。
  • throw方法,让调用方抛出异常,在生成器中处理。
  • close()方法,终止生成器。

python3.3中为了更好地作为协程使用,对生成器句法做了两处改动:

  • 现在,生成器可以返回一个值,以前如果在生成器中给return语句提供值,会抛出SyntaxError异常。
  • 新引入了yield from句法,使用它可以把复杂的生成器重构成小型的嵌套生成器,省去了之前把生成器的工作委托给子生成器所需的大量代码。

二、用作协程的生成器的基本行为

  1. 协程使用生成器函数定义:定义体中有yield关键字。
  2. yield在表达式中使用,如果协程只需要从客户那里接收数据,那么yield产出的值是None,这个值是隐式指定的,因为yield关键字右边没有表达式。也就是说,yield表达式右边才是生成器要产出的值,如果右边没有表达式,则相当于隐式指定产出None。
  3. 调用生成器函数得到生成器对象。
  4. 首先要调用next()函数,因为生成器还没启动,没在yield语句处暂停,所以一开始无法发送数据。
  5. 生成器对象调用send方法,参数即为调用者要发送的数据,本例中协程定义体中的yield表达式会计算出42,调用完send方法之后,协程会恢复,一直运行到下一个yield表达式,或者终止。
  6. 控制权流动到协程定义体的末尾,导致生成器像往常一样抛出StopIteration异常。

协程可以身处四个状态中的一个,当前状态可以使用inspect.getgeneratorstate()函数确定,该函数会返回以下字符串中的一个:

  • ‘GEN_CREATED’,等待开始执行。
  • ‘GEN_RUNNING’,解释器正在执行。
  • 'GEN_SUSPENDED',在yield表达式处暂停。
  • 'GEN_CLOSED',执行结束。

因为send方法的参数会成为暂停的yield表达式的值,所以仅当协程处于暂停状态时才能调用send方法,例如my_coro.send(42),但是,如果协程还没激活(即处于GEN_CREATED"状态),则会发生错误。因此在send真正的数据之前必须要先激活协程,有两种方法激活协程:

  1. 调用next(my_coro)。
  2. 调用my_coro.send(None),即发送None值给协程对象。

如果创建协程之后立即把None之外的值发给它,会出现以下错误:

预激协程:即最先调用next(my_coro)函数这一步,让协程向前执行到第一个yield表达式,准备好作为活跃的协程使用。

        上边例子协程只产出了一个值,下边例子协程产出两个值:

  1. inspect.getgeneratorstate函数指明,协程未启动,即处于GEN_CREATED状态。
  2. 预激协程,即向前执行协程到第一个yield表达式,打印 -> Started: a = 14,然后yield a产出a的值(14),并且暂停,等待为b赋值。
  3. getgenetatorstate函数指明,协程处于GEN_SUSPENDED状态,即协程在yield表达式处暂停。
  4. 把数字28发送给暂停的协程,计算yield表达式得到28,然后把28绑定给b。然后协程继续执行,打印消息,执行到第二个yield处,产出 a + b的值42,然后协程再次暂停,等待调用者发送数据并赋值给c。
  5. 把数字99发给暂停的协程,此时计算yield表达式得到99,然后把99绑定给c,继续执行协程。因为下边已经没有yield了,因此执行到协程终止,导致生成器抛出StopIteration异常。
  6. getgeneratorstate函数指明,协程执行结束,处于GEN_CLOSED状态。

关键一点是,协程在yield关键字所在的位置暂停执行。在赋值语句中,=右边的代码在赋值之前之宗,因此,对于 b = yield a这行代码来说,等到客户端代码再激活协程时才会给b赋值。

三、使用协程计算移动平均值 

  1. 这个无线循环表明,只要调用方不断把值发给这个协程,他就会一直收值,然后生成结果。仅当调用方在协程中调用.close()方法,或者没有对协程的引用而被垃圾回收程序回收时,这个协程才会终止。
  2. yield表达式用于暂停执行协程,把结果发给调用方;还用于接收调用方后面发给协程的值,恢复无线循环。

使用协程的好处是total和count声明为局部变量即可,无需使用实例属性或闭包在多次调用之间保持上下文。

  1. 创建协程对象。
  2. 调用next函数,预激协程。
  3. 计算移动平均值,多次调用.send()方法,产出当前的平均值。

调用next(coro_avg)预激协程后,协程会向前执行到yield表达式,产出average变量的初始值------None,因此不会出现在控制台中。

四、预激协程的装饰器

如果不预激,则协程没什么用。因为调用my_coro.send(x)之前,一定要调用next(my_coro)。当时很多时候容易忘记预激,为了简化协程的用法,有时会使用一个预激装饰器,比如coroutine。

        下面是装饰器coroutine的源码,@wraps是python内置的一个装饰器,其通常放在装饰器的源码中用来修饰内函数,其作用是消除装饰器装饰过函数以后,被装饰函数的函数名等属性被修改的副作用。

  1. 把被装饰的生成器函数替换成这里的primer函数;调用primer函数,返回预激后的生成器。
  2. 调用被装饰的函数,获取生成器对象。
  3. 预激生成器。
  4. 返回生成器。

下面用@coroutine装饰器定义并测试计算移动平均值的协程。

  1. 调用average生成器函数创建一个生成器对象,在coroutine装饰器的primer函数中已经预激了这个生成器。
  2. getgeneratorstate函数表明,协程处于GEN_SUSPENDED状态,因此协程已经准备好可以接收值了。
  3. 可以立即把值发送给coro_avg,这正是coroutine装饰器的作用,防止调用者忘记预激协程。
  4. 导入coroutine装饰器。
  5. 把装饰器应用到averager函数上。
  6. 函数定义体与上一个版本完全一样。

五、终止协程和异常处理

协程中未处理的异常会向上冒泡,传给next函数或send方法的调用方(即触发协程的对象)。如下案例:

  1.  使用@coroutine装饰器装饰的averager协程,可以立即开始发送值。
  2.  发送的值不是数字,导致协程内部有异常抛出。
  3.  由于在协程内没有处理异常,协程会终止,如果试图重新激活协程,会抛出StopIteration异常。

出错的原因是,发送给协程的'spam'值不能加到total变量上。

发送哨符值让协程退出

内置的None和Ellipsis等常量经常用作哨符值。Ellipsis的优点是,数据流中不太常有这个值。还可以把StopIteration类本身(不是实例)作为哨符值,即my_coro.send(StopIteration)。

使用throw和close显式把异常发给协程

generator.throw(exc_type[, exc_value[, traceback]])

致使生成器在暂停的yield表达式处抛出指定的异常。

  • 如果生成器处理了抛出的异常,代码向前执行到下一个yield表达式,而产出的值会成为调用generator.throw方法得到的返回值。
  • 如果生成器没有处理抛出的异常,异常会向上冒泡,传到调用方的上下文中。

generator.close()

致使生成器在暂停的yield表达式处抛出GeneratorExit异常。

  • 如果生成器没有处理这个异常,或者抛出了StopIteration异常(通常指运行到结尾),调用方不会报错。
  • 如果收到GeneratorExit异常,生成器一定不能产出值,否则解释器会抛出RuntimeError异常。
  • 生成器抛出的其他异常会向上冒泡,传给调用方。

使用close和throw控制协程例子

 

  1. 特别处理DemoException异常。
  2. 如果没有异常,那么显示接收到的值。
  3. 这一行永远不会执行。因为只有未处理的异常才会中止无限循环,而一旦出现未处理的异常,协程会立即终止。

没有异常时,协程demo_exc_handling使用情况如下:

 

把异常DemoException传入demo_exc_handling(用throw)不会导致协程中止:

可以看到如果传入协程的异常得到处理,则协程状态变成'GEN_SUSPENDED',即协程在yield表达式处暂停。此时应该可以由调用发继续给协程发送值。

        但是,如果传入协程的异常没有处理,协程会停止,即状态变成‘GEN_CLOSED’,如下:

 如果不管协程如何结束都想做些清理工作,要把协程定义体中相关的代码放入try/finally块中:

六、让协程返回值

如下例子中,每次迭代时协程不会产出值,而是在最后返回一个namedtuple,具名元组有两个字段,分别时项数count和平均值average。

  1.  为了返回值,协程必须正常终止,因此这一版中用一个条件判断来退出累计循环。
  2.  返回一个具名元组,包含count和average两个字段,在python3.3之前,如果生成器返回值,解释器会报语法错误。

  1.  这一版不产出值。
  2.  发送None会终止循环,导致协程结束,返回最终结果。协程结束会抛出StopIteration异常,异常对象的value属性保存着返回值。

在协程中,return表达式的值会传给调用方,赋值给StopIteration异常的一个属性,这样做有点不太合理,但是能保留生成器对象的常规行为------耗尽时抛出StopIteration异常。可以直接捕获这个异常,获取协程返回的值:

以上获取协程返回值要绕个圈子,而使用yield from结构会在内部自动捕获StopIteration异常,这种处理方式与for循环处理StopIteration异常的方式一样,对yield from结构来说,解释器不仅会捕获StopIteration异常,还会把value属性的值变成yield from表达式的值。但是我们无法在控制台测试这种行为,因为函数外部使用yield from 以及yield会导致语法错误。

七、使用yield from

使用yield from简化for循环中的yield表达式:

使用yield from可以链接可迭代的对象:

综上可以看出,yield后边跟的是迭代时实际产出的对象,而yield from后面跟的是可迭代对象,要产出的是可迭代对象中的元素。yield from x表达式对x对象做的第一件事就是调用iter(x)获取迭代器,因此x可以是任何可迭代对象(只要实现了iter方法就是可迭代对象)。

        但yield from结构的作用不止是替代产出值得for循环,而要发散思维,使用嵌套的生成器,yield from结构是把职责委托给子生成器的句法。yield from的主要功能是打开双向通道,把最外层的调用方与最内层的子生成器连接起来,这样二者可以直接发送和产出值,还可以直接传入异常,而不用在位于中间的协程中添加大量处理异常的代码。

        为了使用yield from,PEP380使用了一些专门术语:

  • 委派生成器,包含yield from <iterable>表达式的生成器函数。
  • 子生成器,从yield from 表达式中<iterable>部分获得的生成器。
  • 调用方,调用了委派生成器的客户端代码。有些语境中等价于客户端。

下图展示调用方、委派生成器、和子生成器各自的使用:

委派生成器在yield from表达式处暂停时,调用方可以直接把数据发给子生成器,子生成器再把产出的值发给调用方。子生成器返回(迭代结束)之后,解释器会抛出StopIteration异常,并把返回值附加到异常对象上,此时委派生成器会恢复。

        以下示例说明yield from结构的用法:

 

 

  1.  averager协程,用于计算移动平均值,返回一个具名元组,这里作为子生成器使用。
  2.  main函数中的客户代码发送的各个值绑定到这里的term变量上。
  3.  终止条件,如果没有这个,则使用yield from调用这个协程的生成器会永远阻塞。
  4.  协程的返回值,返回的Result会成为grouper函数中yield from表达式的值。
  5.  grouper是委派生成器。
  6.  这个循环每次迭代时都会创建一个新的averager实例,每个实例都是作为协程使用的生成器对象。
  7.  通过grouper发送的每个值,都会经过yield from处理,通过管道传给averager实例。grouper会在yield from表达式处暂停,等待averager实例处理客户端发来的值(即客户端通过grouper.send来给averager中的yield语句传值)。averager实例运行完毕后,返回的值绑定到results[key]上。
  8. main函数是客户端代码,是调用方。
  9.  group是调用grouper函数得到的生成器对象,传给grouper函数的第一个参数是results,用于手机结果;第二个参数是某个键。group作为协程使用。
  10.  预激group协程。
  11.  把各个value传给grouper,传入的值最终到达averager函数中,用来给term赋值,grouper永远都不知道传入的值是什么。
  12.  把None传入grouper,导致当前的averager实例终止,也让grouper继续运行,再创建一个averager实例,处理下一组值。

下面简要说明上例运作方式:

  • 外层for循环每次迭代会新键一个grouper实例,赋值给group变量,group是委派生成器。
  • 调用next(group),预激委派生成器group,此时进入while True循环,调用子生成器averager后,group在yield from表达式处暂停。
  • 内层for循环调用group.send(value),直接把值传给子生成器averager。同时当前的grouper实例group在yield from处暂停。
  • 内层循环结束后,group实例依旧在yield from表达式处暂停,因为averager实例还没有结束,因此,grouper函数体中未results[key]赋值的语句还没有执行。
  • 如果外层for循环的末尾没有group.send(None),那么averager子生成器就永远不会终止,委培生成器group永远不会再次激活(会一直暂停在yield from),因此永远不会未results[key]赋值。
  • 外层for循环重新迭代时会新键一个grouper实例,然后绑定到group变量上,前一个grouper实例(以及它创建的尚未终止的averager子生成器实例)被垃圾回收程序回收。

这个试验表明,如果子生成器不终止,委派生成器会在yield from表达式处永远暂停,如果是这样,程序不会向前执行,因为yield from和yield一样把控制权转交给了客户代码(委派生成器的调用方)。

        上例展示了yield from结构最简单的用法,只有一个委派生成器和一个子生成器,因为委派生成器相当于管道,所以可以把任意数量个委派生成器连接在一起:一个委派生成器使用yield from调用一个子生成器,子生成器本身也是委培生成器,使用yield from调用另一个子生成器,依次类推。最终,这个链条要以一个只使用yield表达式的简单生成器结束(也可以以任意可迭代对象结束)。

        任何yield from链条都必须由客户驱动,在最外层委派生成器上调用next()函数或.send()方法,可以隐式调用,例如使用for循环。

八、yield from的意义

yield from六点行为

  1. 子生成器产出的值都直接传给委派生成器的调用方(即客户端代码)。
  2. 使用send()方法发给委派生成器的值都直接传给子生成器。如果发送的值是None,那么会调用子生成器的__next__()方法,如果发送的值不是None,那么会调用子生成器的send()方法。如果调用的子生成器的方法抛出StopIteration异常,那么为委派生成器恢复运行。任何其他异常都会向上冒泡,传给委派生成器。
  3. 生成器退出时,生成器(或子生成器)中的return expr表达式会触发StopIteration(expr)异常抛出。
  4. 委派生成器中yield from表达式的值是子生成器终止时传给StopIteration异常的第一个参数。
  5. 传入委派生成器的异常,除了GeneratorExit之外都传给子生成器的throw方法,如果调用throw方法时抛出StopIteration异常,委派生成器恢复运行。StopIteration之外的异常会向上冒泡,传给委派生成器。
  6. 如果把GeneratorExit异常传入委派生成器,或者在委派生成器上调用close方法,那么在子生成器上调用close方法(如果他有)。如果调用close方法导致异常抛出,那么异常会向上冒泡,传给委派生成器,否则委派生成器抛出GeneratorExit异常。

 yield from与异常处理

  1.  EXPR可以是任何可迭代的对象,因为获取迭代器_i(这是子生成器)使用的是iter()函数。
  2.  预激子生成器,结果保存在_y中,作为产出的第一个值。
  3.  如果抛出StopIteration异常,获取异常对象的value属性,赋值给_r(这是最简单情况下的返回值RESULT)。
  4.  运行这个循环,委派生成器会阻塞,只作为调用方和子生成器之间的通道。
  5. 产出子生成器当前产出的元素;等待调用方发送_s中保存的值。
  6. 尝试让子生成器向前执行,转发调用方发送的_s。
  7. 如果子生成器抛出StopIteration异常,获取value属性的值,赋值给_r,然后退出循环,让委派生成器恢复运行。
  8. 返回的结果RESULT是_r,即整个yield from表达式的值。

 

苹果搜索广告ASA开户教程 阅读导航 一、创建账号 1、登录网站 2、填写账号主体信息 3、填写商家和发票信息 4、选择付款方式 二、上传审核材料 1、上传文件 2、请求审批 3、上传文件中的常见问题 一、创建账号 1、用Apple ID登录ASA网站 首先我们进入开户网址:https://app-ads.apple.com/ 如果已拥有Apple ID,直接登录即可,如果没有Apple ID,可以先按照步骤创建Apple ID,再返回登录。 注意,这里登录的Apple ID也有讲究: ① 如果是开发 阅读详情

相关推荐

【实战指南】Green Hills MULTI-IDE 从零安装到工程创建全流程

本文详细介绍了Green Hills MULTI-IDE从零安装到工程创建的全流程,包括系统要求检查、安装步骤、工程配置及调试技巧。特别适合嵌入式开发新手快速上手这款专业IDE工具,提升开发效率。

weixin_28740299的博客 474

ext direct spring Model Generator and Generator APT

ModelGenerator 自1.2.1版本后支持 ExtDirectSpring包含一个简单代码生成器,根据java类生成对应的JavaScript Model对象代码。生成器可以生成Ext JS 4.x和Sencha Touch 2.x两种类库适用代码。 添加代码生成器到程序需要创建一个@Controller注释的类用ModelGenerator.writeModel把Javasc

HelloWorldDemo 1905

版电力系统故障录波_故障录波识图与典型故障波形分析

1、设置故障录波的目的故障录波装置是对电力系统运行状况进行监控的一种自动化设备。系统正常运行时,录波装置不启动录波,当系统发生故障时,通过启动录波装置迅速启动录波器录波,直接记录反应故障装置安装处系统故障的电气量。2、故障录波的作用(1)正确评价继电保护和自动装置的工作。(2)正确分析事故的原因并研究防止对侧。(3)发现继电保护和自动装置缺陷。(4)发现一次设备缺陷,及时消除隐患。(5)帮助寻找故...

weixin_42495661的博客 1万+

生成器、协程

协程

YPeng_Gao的博客 563

玉米群体遗传分析实战:如何用IQtree和VCF文件快速构建系统发育树(附避坑指南)

本文详细介绍了如何利用IQtree和VCF文件进行玉米群体遗传分析,并快速构建可靠的系统发育树。文章重点解析了从VCF格式转换到PHYLIP格式的实用技巧,强调了使用ASC模型校正SNP数据偏差的重要性,并提供了完整的参数设置、常见报错解决方案及结果评估指南,帮助研究者高效完成分析并规避常见陷阱。

leaf8的博客 606

5G NR LDPC码(2)—— 从基图到速率匹配:解码5G高速数据信道的标准化设计

本文深入解析了5G NR LDPC码的标准化设计流程。从作为核心骨架的基图(BG1/BG2)出发,详细阐述了其如何通过扩展因子Z灵活生成实际校验矩阵,并协同传输块大小计算与分段策略。文章重点剖析了基于循环缓存和冗余版本的速率匹配机制,以及其如何高效支撑增量冗余混合自动重传请求,从而确保5G高速数据信道在复杂环境下的可靠与高效传输。

weixin_29206669的博客 271

生成器里面的 return 有什么用?

↑↑↑关注后"星标"简说Python人人都可以简单入门Python、爬虫、数据分析简说Python推荐 来源:未闻Code作者:kingname 在粉丝群里,有一位同学...

简说Python的博客 617

贝叶斯机器学习在吸附量预测中的应用

本文介绍了贝叶斯机器学习在吸附量预测中的应用。通过Python实现完整的贝叶斯建模流程,包括数据生成、预处理、模型构建与评估。文章对比了贝叶斯与频率学派的差异,详细阐述了贝叶斯线性回归和神经网络的实现方法,并提供了数据可视化、模型诊断等技术细节。该方法不仅能预测吸附量,还能量化预测不确定性,为工程决策提供更全面的依据。全文超过6000字,结合理论推导与代码实践,是应用贝叶斯方法解决实际工程问题的完整指南。

AI的内部世界的博客 165

生成器

一、什么是生成器 生成器是一类特殊的迭代器。 利用迭代器,我们可以在每次迭代获取数据(通过next()方法)时,按照特定的规律进行数据的生成。 为什么要提出生成器? 在实现一个迭代器时,当前迭代到的状态需要我们自己记录,才能根据当前状态生成下一个数据。 为了实现记录当前状态,并配合next()函数进行迭代使用。 可以采用更简便的语法,即生成器(generator)。 二、生成器的...

松鼠豪的坚果 763

10、硬件工程师笔试面试——继电器(2025版本)

在设计电路时,应综合考虑SSR的优势和局限性,确保选择合适的型号,并采取适当的设计措施来优化性能和可靠性。继电器的主要功能是利用较小的电流或电压来控制较大电流或电压的电路,实现信号的放大和隔离。在处理继电器故障时,应综合考虑电源、线圈、触点和负载等因素,及时进行故障诊断和处理,以确保电路系统的稳定性和安全性。由于汽车电子系统的复杂性,继电器的设计和选择必须考虑到系统的特定要求,包括电流容量、电压等级、环境条件(如温度、湿度、振动)以及所需的保护和隔离功能。确定线圈的工作电压或电流,以及吸合电压或电流。

XU157303764的博客 3732

基于Matlab的深度学习OFDM系统信号检测

在接收端,我们首先去除循环前缀,然后对接收到的信号进行FFT变换和QAM解调。在通信系统中,正交频分复用(Orthogonal Frequency Division Multiplexing,OFDM)是一种常用的调制技术,它可以将高速数据流分成若干个低速子载波进行传输,提高了信道利用率和抗干扰性能。接下来,我们使用训练好的神经网络对QAM调制后的数据进行检测,得到估计的FFT变换结果。深度学习方法可以通过大量的训练数据来学习信号的特征,并具有一定的适应能力,在某些情况下可能能够获得更好的检测性能。

2301_79325657的博客 296

流畅python学习笔记:第十六章:协程

通常在python进行编程一般都是使用多线程或者多进程来实现。这里介绍另外一种并发的方式,就是协程,但和多线程以及多进程不一样的是,协程是运行在单线程当中的并发。来看下具体的例子: def simple_coroutine(): print 'corouting started' x=yield (1) print 'coroutine receive...

dianjie9145的博客 269

AWR2243的等效相位中心与虚拟通道

在俯仰维方向上,不重合的虚拟通道有8个,排序为1:4,9:12。每个虚拟阵元之间的间隔为lambda/2。实际y轴方向虚拟阵列只跨越了8*lambda/2的距离。等效相位中心与虚拟通道类似,只是每个相位中心之间间隔为lambda/4,实际y轴方向等效相位中心只跨越了8*lambda/4=7.59mm的距离

qq_50974341的博客 1981

python编程16章_流畅python学习笔记:第十六章:协程

通常在python进行编程一般都是使用多线程或者多进程来实现。这里介绍另外一种并发的方式,就是协程,但和多线程以及多进程不一样的是,协程是运行在单线程当中的并发。来看下具体的例子:defsimple_coroutine():print 'corouting started'x=yield (1)print 'coroutine received %d'% xif__name__=="__mai...

weixin_39687814的博客 227

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

流畅的python(十六)—协程

协程终止 generator.close() 该方法是正确的关闭协程的方法,只要协程按照下面的说法写代码,当调用此函数时,协程立刻关闭;协程关闭后就不能再send数据了,否者会报出StoIteration这个错误。关闭协程除了不能send数据这个方法之外,还可以调用inspect里面的getgeberatorstate()方法返回这个协程的状态,这个也可以判断,一般而言方法就这...

飞奔的WSL-WLL 239

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

流畅的Python(十六)-协程

1. 生成器作为协程使用时的行为状态2.使用装饰器自动预激协程3.调用方使用close和throw方法控制协程4.协程终止时如何返回值5.yield from新句法的用途和语义6.案例:出租车队运营仿真。

weixin_37901366的博客 655

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

流畅的python第十六章协程学习记录

从句法上看,协程与生成器类似,都是定义体中包含 yield 关键字的函数。可是,在协程中,yield 通常出现在表达式的右边(例如,datum = yield),可以产出值,也可以不产出——如果 yield 关键字后面没有表达式,那么生成器产出 None。协程可能会从调用方接收数据,不过调用方把数据提供给协程使用的是 .send(datum) 方法,而不是next(...) 函数。通常,...

anyangyu0343的博客 159

流畅的 python 新手_流畅的python第十六章协程学习记录

从句法上看,协程与生成器类似,都是定义体中包含 yield 关键字的函数。可是,在协程中,yield 通常出现在表达式的右边(例如,datum = yield),可以产出值,也可以不产出——如果 yield 关键字后面没有表达式,那么生成器产出 None。协程可能会从调用方接收数据,不过调用方把数据提供给协程使用的是 .send(datum) 方法,而不是next(...) 函数。通常,调用方会把...

weixin_39925031的博客 102

流畅的python 阅读笔记

流畅的python阅读笔记(未完结)

翻车的博客 4105

《流畅的Python》第十六章学习笔记

协程的四个状态使用inspect.getgeneratirstat()获取协程的状态等待开始执行GEN_CREATED解释器正在执行GEN_RUNNING在yield表达式处暂停GEN_S...

测试游记 169

python 生成器-协程示例代码的问题与讨论:yield、yield from、send

本文着重讨论《流畅的python》一书中第十六章第七小节中对yield from使用的示例代码及其疑似误导的注解。(个人认为试例代码的注解有些不明确,会使入门读者产生歧义且“不明觉厉”) 重要的事情再说一遍。。这是个人见解但给出了观点及其理由and这就是个希望发起讨论的文章 有关yield关键字及生成器与协程请见其他博客。 源代码见https://github.com/l65775622/...

logo5551的博客 365

python:并发编程(二十六)

本文将和大家一起探讨python并发编程的实际项目:win图形界面应用(篇八,共八篇),系列文章将会从零开始构建项目,并逐渐完善项目,最终将项目打造成适用于高并发场景的应用。

weixin_43431593的博客 573

流畅的python是python3吗_《流畅的Python》读书笔记一

通过内置的函数(例如 len、iter、str,等等)来使用特殊方法是最好的选择。这些内置函数不仅会调用特殊方法,通常还提供额外的好处,而且对于内置的类来说,它们的速度更快Python 有一个内置的函数叫 repr,它能把一个对象用字符串的形式表达出来以便辨认,这就是“字符串表示形式”。repr 就是通过 __repr__这个特殊方法来得到一个对象的字符串表示形式的生成器表达式的语法跟列表推导差不...

weixin_39879122的博客 101

python cookbook 流畅的python_流畅的python和cookbook学习笔记(四)

1.数字的四舍五入对于简单的舍入运算,使用内置的 round(value, ndigits) 函数即可。round 函数返回离它最近的偶数。也就是说,对 1.5 或者 2.5 的舍入运算都会得到 2。>>> round(2.5)2>>> round(1.5)2round()的参数ndigits可以是负数,取整到十位,百位,千位, 效果如下:>>&gt...

weixin_39988476的博客 292

《流畅的Python第二版》读书笔记——文本和字节序列

主要讨论 Unicode 字符串、字节序列,以及在二者之间转换时使用的编码。

日积月累,天道酬勤 1631

《流畅的Python》读书笔记——Python文本和字节序列

字符问题 从Python3的str对象获取的元素时Unicode字符,相当于从Python2的unicode对象中获取的元素,而不是从Python2的str对象中获取的原始字节序列。 把码位(字符的标识)转换成字节序列的过程是编码;把字节序列转换成码位的过程是解码: >>> s = 'café' >>> len(s)#4个Unicode字符 4 >&gt...

日积月累,天道酬勤 1150
上一篇: 流畅的python笔记(十五)上下文管理器和else块
下一篇: 流畅的python笔记(十七)使用期物处理并发
罗古洞的女婿
博客等级 码龄10年 1117粉丝 125原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值