当前位置: 首页 > 编程日记 > 正文

Python3中生成器介绍

生成器(generator):一个返回生成器迭代器的函数。它看起来像一个普通函数,除了它包含用于生成一系列可在for循环中使用的值的yield表达式或者可以使用next函数一次检索一个值。

在Python中,使用了yield的函数被称为生成器。跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作。生成器函数一般是通过for循环调用,for循环自带next方法。

生成器迭代器(generator iterator):由生成器函数(generator function)创建的对象。每个yield暂时挂起处理,记住位置执行状态(包括局部变量和挂起的try语句)。当生成器迭代器恢复时,它从停止的地方开始(与每次调用都重新开始的函数相反)。

生成器表达式(generator expression):返回迭代器的表达式。它看起来像一个普通表达式,后跟一个定义循环变量、范围和可选if子句的for子句。

yield 表达式(yield expression):用在定义生成器函数或异步生成器函数,它只能在函数定义体中使用。在函数体中使用yield表达式会使该函数成为生成器。

当一个生成器函数被调用时,它返回一个称为生成器的迭代器。该生成器控制生成器函数的执行。当调用生成器的任一方法时,执行开始。此时,继续执行第一个yield表达式,在那里它再次挂起,将expression_list的值返回给生成器的调用者。挂起是指保留所有局部状态,包括局部变量的当前绑定、指令指针、内部计算堆栈以及任何异常处理的状态。当通过调用生成器的任一方法恢复执行时,该函数可以像yield表达式被另一个外部调用继续执行。恢复后的yield表达式的值取决于恢复执行的方法。如果使用__next()__(通常通过for或next()内置函数),则结果为None。否则,如果使用send(),则结果将是传递给该方法的值。

在try结构中的任何地方都允许使用yield表达式。如果生成器在完成之前没有恢复,生成器迭代器的close()方法将被调用,允许任何挂起的finally子句执行。

当使用yield from <expr>时,提供的表达式必须是可迭代的。迭代产生的值直接传递给当前生成器方法的调用者。如果底层迭代器有适当的方法,任何用send()传入的值和用throw()传入的任何异常都被传递给底层迭代器。如果不是这种情况,则send()将触发AttributeError或TypeError,而throw()将立即触发传入的异常。当底层迭代器完成时,触发的StopIteration实例的value属性成为yield表达式的值。它可以在触发StopIteration时显式设置,也可以在子迭代器是生成器时自动设置。

yield语句:在语义上等同于yield表达式。yield表达式和语句仅用在定义生成器函数中。在函数中使用yield便会创建生成器函数。

yield语句暂停函数的执行并将一个值发送回调用者,但保留足够的状态以使函数能够从停止的地方恢复。恢复后,该函数会在最后一次yield运行后立即继续执行。这允许它的代码随着时间的推移产生一系列值,而不是一次计算它们并像列表一样发送它们。

当yield表达式是赋值语句右侧的唯一表达式时,可以省略括号。

生成器迭代器方法:它们可用于控制生成器函数的执行。当生成器已经在执行时调用下面的任何生成器方法都会触发ValueError异常。

(1).generator.__next__():开始执行生成器函数或在最后一次执行的yield表达式处继续执行。当使用__next__()方法恢复生成器函数时,当前的yield表达式总是计算为None。然后继续执行下一个yield表达式,在那里生成器再次挂起,并且expression_list的值返回给__next__()的调用者。如果生成器退出而没有产生另一个值,则会触发StopIteration异常。此方法通常被隐式调用,例如通过for循环或内置的next()函数。

(2).generator.send(value):恢复执行并将value ”sends”到生成器函数中。value参数成为当前yield表达式的结果。send()方法返回生成器生成的下一个值,或者如果生成器退出而没有生成另一个值则触发StopIteration。当调用send()来启动生成器时,必须以None作为参数调用它,因为没有可以接收值的yield表达式。

(3).generator.throw(type[, value[, traceback]]):在生成器暂停时触发类型的异常,并返回生成器函数产生的下一个值。如果生成器退出而没有产生另一个值,则会触发StopIteration异常。如果生成器函数没有捕获传入的异常,或者触发不同的异常,则该异常会传递给调用者。

(4).generator.close():在生成器函数暂停的位置触发GeneratorExit。如果生成器函数随后正常退出、已关闭或触发GeneratorExit,则close返回到其调用者。如果生成器产生一个值,则会触发RuntimeError。如果生成器触发任何其它异常,则会将其传递给调用者。如果生成器由于异常或正常退出而退出,则close()不执行任何操作。

以上内容主要翻译于:7. Simple statements — Python 3.9.7 documentation

测试代码如下:

var = 1
if var == 1:# reference: https://docs.python.org/3/reference/expressions.html#yieldexprdef echo(value=None):print("Execution starts when 'next()' is called for the first time.")try:while True:try:value = (yield value)print("value:", value)except Exception as e:value = efinally:print("Don't forget to clean up when 'close()' is called.")generator = echo(1) # 此处echo函数并未真的执行,返回generator对象print("object:", generator)print(next(generator)) # 当调用next或__next__时,echo函数才正式开始执行print(next(generator))print("start send"); print(generator.send(10)); print("end send")generator.throw(TypeError, "spam")generator.close()
elif var == 2:# reference: https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-domylist = [x*x for x in range(3)]  # mylist is an iterable,  you store all the values in memoryfor i in mylist:print(i)# Generators are iterators, a kind of iterable you can only iterate over once.# Generators do not store all the values in memory, they generate the values on the flymygenerator = (x*x for x in range(3))for i in mygenerator:print(i)for i in mygenerator:print(i) # 第二次for in不会有任何值输出, generators can only be used once# yield is a keyword that is used like return, except the function will return a generatordef create_generator():print("start ...")mylist = range(3)for i in mylist:yield i*imygenerator2 = create_generator() # create a generatorprint("object:", mygenerator2) # mygenerator2 is an objectprint("value:", mygenerator2.__next__())for i in mygenerator2:print(i)for i in mygenerator2:print(i) # 第二次for in不会有任何值输出# To master yield, you must understand that when you call the function, the code you have# written in the function body does not run. The function only returns the generator object.# Then, your code will continue from where it left off each time for uses the generator.
elif var == 3:# reference: https://www.geeksforgeeks.org/use-yield-keyword-instead-return-keyword-python/# The yield statement suspends function’s execution and sends a value back to the caller, but retains enough# state to enable function to resume where it is left off. When resumed, the function continues execution# immediately after the last yield run.def simpleGeneratorFun():yield 1yield 2yield 3for value in simpleGeneratorFun():print(value)# An infinite generator function that prints next square number. It starts with 1def nextSquare():i = 1# An Infinite loop to generate squareswhile True:yield i*ii += 1 # Next execution resumes from this pointprint("object:", nextSquare())for num in nextSquare():if num > 100:breakprint(num) # the first value is 1print("go on:")print("object:", nextSquare())for num in nextSquare():if num > 200:breakprint(num) # note: the first value is still 1, instead of 121print("test finish")

GitHub:https://github.com/fengbingchun/Python_Test

相关文章:

数学学渣必备!拍照上传,分步求解,微软解题神器拯救你

整理 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;在学好数学这条路上&#xff0c;很多同志前赴后继「死伤无数」&#xff0c;即便大家不断的寻求「场外救援」&#xff0c;可最终都逃不过一个字&#xff1a;难&#xff01;两个字&#xff1a;真难…

Java业务代表模式

业务代表模式&#xff08;Business Delegate Pattern&#xff09;用于对表示层和业务层解耦。它基本上是用来减少通信或对表示层代码中的业务层代码的远程查询功能。在业务层中我们有以下实体。 客户端&#xff08;Client&#xff09; - 表示层代码可以是 JSP、servlet 或 UI j…

在wamp环境下面安装Zend Optimizer的方法

我是用WAMP来做PHP的服务器&#xff0c;进行本机测试和开发PHP项目。 wamp环境是刚刚安装的。由于这个项目的代码是zend加密的&#xff0c;运行时候都是乱码&#xff0c;需要安装一个Zend Optimizer配置。 首先下载一个Zend Optimizer软件。 1、进入安装界面后&#xff0c;按NE…

libuvc介绍及简单使用

libuvc是一个用于USB视频设备的跨平台库&#xff0c;构建在libusb之上&#xff0c;编译libuvc时需要依赖libusb。libuvc的License为BSD&#xff0c;最新发布版本为0.0.6&#xff0c;源码地址: https://github.com/libuvc/libuvc libuvc支持在非windows系统上直接编译&#xff0…

AI又被彩虹吹!​网易被预言为“下一个百度”?

人工智能到底有多火&#xff1f;近日国内首份《BAT人工智能领域人才发展报告》新鲜出炉&#xff0c;此次报告是针对国内人工智能领域的人才争夺情况进行了梳理。并把研究对象锁定在BAT三大巨头的身上。来源&#xff1a;《BAT人工智能领域人才发展报告》其中得出最为核心的结论&…

Java组合实体模式

组合实体模式&#xff08;Composite Entity Pattern&#xff09;用在 EJB 持久化机制中。一个组合实体是一个 EJB 实体 bean&#xff0c;代表了对象的图解。当更新一个组合实体时&#xff0c;内部依赖对象 beans 会自动更新&#xff0c;因为它们是由 EJB 实体 bean 管理的。以下…

JAVA的StringBuffer类

StringBuffer类和String一样&#xff0c;也用来代表字符串&#xff0c;只是由于StringBuffer的内部实现方式和String不同&#xff0c;所以StringBuffer在进行字符串处理时&#xff0c;不生成新的对象&#xff0c;在内存使用上要优于String类。 所以在实际使用时&#xff0c;如果…

程序员请收好:10个非常有用的Visual Studio Code插件

作者 | Daan译者 | Elle出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;【导读】一个插件列表&#xff0c;可以让你的程序员生活变得轻松许多。无论你是经验丰富的开发人员还是刚刚开始第一份工作的初级开发人员&#xff0c;你都会想让自己的开发工作尽可能轻松一点…

Python3中装饰器介绍

Python中的装饰器(decorator)是一个接受另一个函数作为参数的函数。装饰器通常会修改或增强它接受的函数并返回修改后的函数。这意味着当你调用一个装饰函数时&#xff0c;你会得到一个与基本定义相比可能有一些额外特性的函数。Python中的函数可以用作或作为参数传递。 Python…

Java数据访问对象模式

数据访问对象模式&#xff08;Data Access Object Pattern&#xff09;或 DAO 模式用于把低级的数据访问 API 或操作从高级的业务服务中分离出来。以下是数据访问对象模式的参与者。 数据访问对象接口&#xff08;Data Access Object Interface&#xff09; - 该接口定义了在一…

hdoj 5199 Gunner map

Gunner Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid5199 Description Long long ago, there is a gunner whose name is Jack. He likes to go hunting very much. One day he go to the grove. There are n birds and n tr…

Python3中上下文管理器介绍

在任何编程语言中&#xff0c;文件操作或数据库连接等资源的使用都很常见。但这些资源供应有限。因此&#xff0c;主要问题在于确保在使用后释放这些资源。如果不释放它们&#xff0c;则会导致资源泄漏&#xff0c;并可能导致系统变慢或崩溃。如果用户有一个自动设置和拆卸资源…

LatentFusion:华盛顿大学与英伟达联合提出6D姿态估计新方法

作者 | Keunhong Park、Arsalan Mousavian、Yu Xiang、Dieter Fox 译者 | 刘畅 编辑 | Jane 出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09; 【导读】在本文中&#xff0c;华盛顿大学和英伟达联合提出了一种新的用于未见过目标 6D姿态估计的框架。作…

Java前端控制器模式

前端控制器模式&#xff08;Front Controller Pattern&#xff09;是用来提供一个集中的请求处理机制&#xff0c;所有的请求都将由一个单一的处理程序处理。该处理程序可以做认证/授权/记录日志&#xff0c;或者跟踪请求&#xff0c;然后把请求传给相应的处理程序。以下是这种…

提供第三种代码生成方式——通过自定义BuildProvider为ASP.NET提供代码生成

2019独角兽企业重金招聘Python工程师标准>>> 之前写了一些关于代码生成的文章&#xff0c;提供了两种不同方式的代码生成解决方案&#xff0c;即CodeDOMCustom Tool和T4。对于ASP.NET应用&#xff0c;你还有第三种选择——自定义BuildProvider。[文中涉及的源代码从…

Java拦截过滤器模式

拦截过滤器模式&#xff08;Intercepting Filter Pattern&#xff09;用于对应用程序的请求或响应做一些预处理/后处理。定义过滤器&#xff0c;并在把请求传给实际目标应用程序之前应用在请求上。过滤器可以做认证/授权/记录日志&#xff0c;或者跟踪请求&#xff0c;然后把请…

1200亿次日均位置服务响应、20亿公里日均轨迹里程,百度地图发布新一代人工智能地图生态全景

12月10日&#xff0c;百度地图首次公布了“新一代人工智能地图”生态全景。目前&#xff0c;百度地图日均位置服务请求次数突破1200亿次&#xff0c;日均轨迹里程20亿公里&#xff0c;注册开发者数量达180万&#xff0c;服务超过50万个移动应用。 百度地图事业部总经理李莹称&…

Python3中global/nonlocal用法

全局变量(global variable)是那些未在任何函数内部定义并且具有全局作用域的变量&#xff0c;而局部变量(local variable)是那些在函数内部定义并且其作用域仅限于该函数的变量。换句话说&#xff0c;我们可以说局部变量只能在初始化它的函数内部访问&#xff0c;而全局变量在整…

客户端动态调用WCF服务中的方法

首先要写一个执行动态调用的方法&#xff1a;在里面实现反射调用。 public static object ExecuteMethod<T>(string pUrl,string pMethodName, params object[] pParams) { EndpointAddress address new EndpointAddress(pUrl); Binding bindinginstance null; NetTcpB…

Python3中闭包介绍

Python3中的闭包(closure)是一个函数对象&#xff0c;它记住封闭作用域(enclosing function)中的值&#xff0c;即使它们不存在于内存中。它是一个将函数与环境一起存储的记录。由于闭包用作回调函数&#xff0c;因此它们提供了某种数据隐藏&#xff0c;这有助于我们减少使用全…

Java服务定位器模式

服务定位器模式&#xff08;Service Locator Pattern&#xff09;用在我们想使用 JNDI 查询定位各种服务的时候。考虑到为某个服务查找 JNDI 的代价很高&#xff0c;服务定位器模式充分利用了缓存技术。在首次请求某个服务时&#xff0c;服务定位器在 JNDI 中查找服务&#xff…

用AI加速物联网落地,安富利的客户洞察和解决之道

作为一家全球IT解决方案分销商&#xff0c;成立于1921年的安富利也紧随AI浪潮&#xff0c;为区域和全球的终端客户提供AI解决方案。据了解&#xff0c;安富利已为全球超过1400家企业提供技术支持&#xff0c;电子产品年度出货量达1220亿片。 近日在媒体沟通会上&#xff0c;安富…

Linux运维工程师发展前景

随着IT产业的不断发展&#xff0c;尤其是Linux行业的发展&#xff0c;现在互联网企业服务器数量越来越多&#xff0c;当到达几百台&#xff0c;上千台服务器之后&#xff0c;服务器日常管理也逐渐繁杂&#xff0c;每天如果通过人工去频繁的更新或者部署及管理这些服务器&#x…

Python3中__init__.py文件介绍

Python中的模块是包含Python定义和语句的文件(A module is a file containing Python definitions and statements)&#xff0c;其文件名是模块名加后缀名.py。在模块内部&#xff0c;通过全局变量__name__可以获取模块名。 模块包含可执行语句及函数定义。这些语句用于初始化模…

赠书 | 熵的实际应用,赌场和金融圈最著名的一个数学公式

本文选自湛庐文化策划出版图书《模型思维》。作者斯科特佩奇&#xff0c;超过100万用户的“模型思维课”主讲人。密歇根大学复杂性研究中心“掌门人”。圣塔菲研究所外聘研究员。曾出版《多样性红利》一书。斯科特佩奇以对社会科学多样性和复杂性的研究和建模面闻名。具体研究方…

Java传输对象模式

传输对象模式&#xff08;Transfer Object Pattern&#xff09;用于从客户端向服务器一次性传递带有多个属性的数据。传输对象也被称为数值对象。传输对象是一个具有 getter/setter 方法的简单的 POJO 类&#xff0c;它是可序列化的&#xff0c;所以它可以通过网络传输。它没有…

图片下方出现几像素的空白间隙

1、如何定义高度很小的容器&#xff1f; 在IE6下无法定义小高度的容器&#xff0c;是因为有一个默认的行高。 列举2种解决方案&#xff1a;overflow:hidden | line-height:0 2、图片下方出现几像素的空白间隙&#xff1f; 这个也有多种解决方案&#xff0c;如将img定义为displa…

Python3中Pillow(PIL)介绍

PIL全称为Python Imaging Library&#xff0c;是Python中的免费开源图像处理库。PIL的最新版本为1.1.7&#xff0c;于2009年9月发布&#xff0c;支持Python的最高版本到2.7。原始的PIL开发于2011年停止。随后&#xff0c;一个名为Pillow的后续项目fork了PIL的repository并增加了…

GitHub有望在中国开设子公司?

作者 | Financial Times译者 | 弯月&#xff0c;编辑 | 郭芮出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;作为世界上最大的软件开发平台&#xff0c;GitHub 自去年被微软以 75 亿美元收购后&#xff0c;一直颇受外界的争议。虽然在交易完成后&#xff0c;GitHub…

OC指示符assign、atomic、nonatomic、copy、retain、strong、week的解释

在使用property定义property时可以在property与类型之间用括号添加一些额外的指示符&#xff0c;常用的指示符有assign、atomic、nonatomic、copy、retain、strong、week、等。详情如下&#xff1a; assign&#xff1a; 简单赋值&#xff0c;不更改索引计数&#xff08;Referen…