我的编程空间,编程开发者的网络收藏夹
学习永远不晚

python yield、yield f

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

python yield、yield f

从生成器到协程

协程是指一个过程,这个过程与调用方协作,产出由调用方提供的值。生成器的调用方可以使用 .send(...)方法发送数据,发送的数据会成为yield表达式的值。因此,生成器可以作为协程使用。

从句法上看,生成器与协程都是包含yield关键字的函数。但是,在协程中,yield通常出现在表达式的右边(* = yield *),可以产出值也可以不产出(yield关键字后边没有表达式,产出None)。

协程有四个状态:

GEN_CREATED:等待开始执行

GEN_RUNNING:正在执行(只有在多线程应用或生成器对象自身调用getgeneratorstate函数可以看到此状态)

GEN_SUSPENDED:在yield表达式处阻塞

GEN_CLOSED:执行结束

使用inspect.getgeneratorstate(...)函数可以查看当前协程的状态。

使用协程的基本步骤为:

  • 创建协程对象
  • 调用next函数,激活协程
  • 调用 .send(...)方法,推动协程执行并产出

一个累积求和的协程示例如下:

如上图示例所示,协程中产出的值会返回给调用方,同时,通过yield将调用方传入的参数赋值给yield表达式左边的变量,并推动协程继续执行。

终止协程和异常处理

因为协程使用生成器函数定义,因此遵循生成器的特性,当协程执行到定义体末尾时,会抛出StopIteration异常。如果协程在执行过程中发生了未处理的异常,协程会终止运行并将异常抛出,此时,试图重新激活协程会抛出StopIteration异常。代码示例:

示例代码中,依然使用累积求和的协程,调用时因为传入了字符串参数,导致协程因TpyeError异常而终止,再次试图调用时,抛出了StopIteration异常。

调用方可以通过调用生成器对象 .throw(exc_type[, exc_value[, traceback]])方法,致使生成器在阻塞的yield表达式处抛出指定的异常。如果生成器处理了抛出的异常,代码会向前执行到下一个yield表达式,产出的表达式会成为 .throw()方法的返回值;如果生成器没有处理抛出的异常,异常会向上冒泡,传到调用方的上下文中。代码示例:

上图示例代码中,协程对TypeError进行了处理,所以当调用方将TpyeError异常发给协程时没有终止;而当调用方将ValueError发给协程时,由于没有处理,协程终止并将异常向上抛给调用方处理,调用方虽然捕获了该异常,但试图再次调用协程时,由于协程已终止,故抛出了StopIteration异常。

调用方可以通过生成器对象的 .close()方法,致使生成器在阻塞的yield表达式处抛出GeneratorExit异常。如果生成器没有处理这个异常,或者抛出了StopIteration异常(通常指运行到程序结尾),调用方不会报错。代码示例:

上图示例代码中,调用 .close()方法后,调用方没有报错,协程终止且返回值为None,试图再次激活协程对象时,会抛出StopIteration异常。

需要注意的是:如果在协程中捕获了GeneratorExit异常,会导致RuntimeError;如果使用 .throw()方法直接将GeneratorExit异常发给协程,调用方会报错并导致GeneratorExit异常。

让协程返回值

有些协程不会产出值,而是在执行结束后返回一个值,而为了返回这个值,协程必须正常终止。代码示例:

上图示例中,协程不再产出值,通过send(None)结束协程,代码执行到最后触发StopIteration异常,而返回值作为StopIteration异常的一个属性返回给调用方。

yield from

yield from是全新的语言结构,多用于嵌套生成器。其主要功能是开辟一个双向通道,把最外层的调用方与最内层的子生成器连接起来,这样二者可以发送/产出值,还可以直接传入异常,而不用在位于中间层的协程中添加大量处理异常的代码。简言之即yield from可以方便的实现生成器嵌套调用并自动处理大部分异常。

理解yield from首先要理解三个概念:

  • 调用方:指委派生成器的客户端代码
  • 委派生成器:包含yield from <iterable>表达式的生成器函数
  • 子生成器:从yield from表达式中<iterable>部分获取的生成器

典型的调用逻辑为:客户端代码(调用方)调用委派生成器对象,委派生成器在yield from表达式处阻塞,此时调用方与子生成器之间的双向通道打开,调用方可以直接把数据发给子生成器,子生成器把产出的值发给调用方。子生成器执行结束,解释器抛出StopIteration异常,并把返回值附加到异常对象上,此时委派生成器恢复执行。委派生成器yield from语句自动处理子生成器抛出的StopIteration异常及附加在异常对象上的返回值。代码示例如下:

注意:委派生成器执行结束时也会抛出StopIteration异常,这里使用了永久循环+全局变量(不推荐)的方式避免委派生成器退出引发StopIteration异常且使客户端能够拿到子生成器返回的结果。实际应用中应视情况进行异常处理。子生成器StopIteration之外未处理的异常会向上冒泡传给委派生成器处理,yield from表达式的值是子生成器终止时传给StopIteration异常的第一个参数。python3.5以后引入了await关键字来替代yield from,使代码更加简洁清晰。

以上。

 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

python yield、yield f

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

python yield、yield f

从生成器到协程协程是指一个过程,这个过程与调用方协作,产出由调用方提供的值。生成器的调用方可以使用 .send(...)方法发送数据,发送的数据会成为yield表达式的值。因此,生成器可以作为协程使用。从句法上看,生成器与协程都是包含yie
2023-01-30

python yield

为了精通 yield ,你必须要理解:当你调用这个函数的时候,函数内部的代码并不立马执行 ,这个函数只是返回一个生成器对象,这有点蹊跷不是吗。那么,函数内的代码什么时候执行呢?当你使用for进行迭代的时候.现在到了关键点了!第一次迭代中你的
2023-01-31

python yield浅析

在python(本文python环境为python2.7)中,使用yield关键字的函数被称为generator(生成器)。故为了了解yield,必然先要了解generator,而了解generator之前,我们先要了解一下迭代。递归和迭代
2023-01-31

Python yield用法

在函数中使用yield时,函数并不会返回数据,而是返回一个生成器对象(generator object),只有当循环遍历时,才会实际运行取得实际的值。示例一是我看到一本书上的例子,示例二是我将它简化后的例子,功能上没有任何区别。#示例一:d
2023-01-31

深入理解 Python yield

yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法。一直到稀里糊涂的看完了廖雪峰的python博客也没彻底明白。 有一次不小心看到了这个文章,是转载的,原文出自哪里我也不知道,08年的文章
2023-01-31

Python之yield生成器

1、对比range和xrange的区别:>>> print range(10)[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>>> print xrange(10)xrange(10)range()和xrange()的区别在于
2023-01-31

python里的生成器--yield

Python的生成器是个很强大的东西,特别是在python3.0版本以后。以最简单的方式让大家快速理解生成器。1、正常的写法来看个例子,比如输出一个自定义长度的列表一般这么写:这里传入的参数时10,所以会得到一个包含10个元素的列表:那当我
2023-01-31

python之yield表达式

yield表达式用于generator function调用generator function时,返回一个iterator(函数内语句不被会执行),调用iterator函数时,执行到yield表达式,当前函数暂停执行,返回表达式的值到调用
2023-01-30

python之yield与装饰器

防伪码:忘情公子著python中的yield:  在之前发布的《python之列表解析与生成器》中我们有提到过,生成器所实现的是跟列表解析近似的效果,但是我们不能对生成器做一些属于列表解析的操作。  因为生成器本身就不是一个列表,它只是模拟
2023-01-31

Python yield 使用方法浅析

如何生成斐波那契?盗?/strong>斐波那契(Fibonacci)?盗惺且桓龇浅<虻サ牡莨槭?校??谝桓龊偷诙?鍪?猓?我庖桓鍪?伎捎汕傲礁鍪?嗉拥玫健S眉扑慊?绦蚴涑鲮巢?瞧?盗械那 N 个数是一个非常简单的问题,许多初学者都可以轻易写
2022-06-04

python怎么正确使用yield

这篇文章主要介绍了python怎么正确使用yield,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。生成器如果在一个方法内,包含了 yield 关键字,那么这个函数就是一个「生
2023-06-15

python yield迭代器详解

带有yield的函数在Python中被称之为generator(生成器),也就是说,当你调用这个函数的时候,函数内部的代码并不立即执行 ,这个函数只是返回一个生成器
2022-11-13

Python中yield的使用方法

这篇文章主要介绍“Python中yield的使用方法”,在日常操作中,相信很多人在Python中yield的使用方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python中yield的使用方法”的疑惑有所
2023-06-15

Python中Yield语法怎么用

这篇文章主要介绍了Python中Yield语法怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Python中Yield语法比如在这里,我们定义了一个fibonacci()
2023-06-27

在Python中如何使用yield

一、生成器 如果在一个方法内,包含了 yield 关键字,那么这个函数就是一个「生成器」。 生成器其实就是一个特殊的迭代器,它可以像迭代器那样,迭代输出方法内的每个元素。 我们来看一个包含 yield 关键字的方法:# coding: ut
2022-06-02

python中yield的用法详解—

此文转载,侵删,原文地址:https://blog.csdn.net/mieleiz...首先,如果你还没有对yield有个初步分认识,那么你先把yield看做“return”,这个是直观的,它首先是个return,普通的return是什么
2023-01-31

python如何正确使用yield

目录生成器nextsendthrowclose使用场景大集合的生成简化代码结构协程与并发总结生成器如果在一个方法内,包含了 yield 关键字,那么这个函数就是一个「生成器」。 生成器其实就是一个特殊的迭代器,它可以像迭代器那样,迭代输出方
2022-06-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录