生成器中send()和next()方法的使用解析

您所在的位置:网站首页 生成器send方法 生成器中send()和next()方法的使用解析

生成器中send()和next()方法的使用解析

2024-07-14 02:30| 来源: 网络整理| 查看: 265

一谈到生成器,往往都会牵扯到next()和send()方法。 下面我们先看一个简单的小例子: 在这里插入图片描述

运行结果如下: 在这里插入图片描述 我将结果分为三个小块分别对应上面例子中的三个print语句。在解释之前我们先简单的了解下函数中有关键字yield的时候next()方法的执行方式。

假设程序中只有一个yield:当第一次调用next方法时,程序会一直执行到yield所在的语句,并执行完该语句,然后跳出,后面的语句不执行,等待下一次调用next()方法。紧接着第二次调用next方法(),程序会从yield所在语句的下一句开始执行,直至程序完全执行完,一次执行完整结束。

如果程序中在含yield部分的语句块中有循环,那么第二次调用next方法的时候,先从yield所在语句的下一行开始执行直到一次循环完成,紧接着下一次循环执行到yield语句时,执行完yield语句,然后再跳出,等待下一次的next()方法的调用,以此类推。

接下来我们分析一下上面的结果,我们先分析第一个和第二个print语句,也就是g.__next__()和next(g)这两句。事先说明一点**g.__next__()和next(g)是等价的**。我们带着刚刚的说的调用next()方法的过程来看这个结果。g.__next__() 打印输出的结果是0,是因为第一次调用next()方法,相当于启动了生成器。当程序执行到yield所在的语句时,执行完这一句,跳出了,此时temp并没有被定义,那为什么又会打印出0呢?这是因为i=0,并yield将0传回了,此时你暂且可以将yield看成return,所以第一个print语句的结果是0。

在第二个print语句之前,我们先介绍一下send的用法: **send()是向yield语句传值,yield语句接收到值以后并将其传回 并且send()方法自带next()方法。**这里有必要解释一下,我们把send看成一个传的值不是空值的next()方法,你们应该就可以明白上面的那句话了。当然send()方法也可以传空值,这里为了方便理解。send()方法传空值时不能在生成器启动时,会出错,这里不做细讲,同学们可以自行查阅。

那么我们再来看看第二个print语句,在分析之前我们先明白一个小知识点,next(g)相当于send(None),这样的话我们就很好分析了,这里有一个重要的点---->以这个例子而言,send向yield语句传值时“yield i”是作为一个整体进行接收值并传回。‘yield i‘接收到send传的值后,会同时把值赋给temp,但在第二次调用next(g)时,程序并没有执行yield所在语句,从它下面的那一句开始执行的 这个地方也需要注意。next(g)看成了send(None),那么“yield i”接收到是None值,temp此时的值也是None值,紧接着i自增了1,此时i=1 满足循环条件,接着下一次循环,程序右执行到yield语句,并执行完,yield将1传回。这就第二个print语句的结果None和1。

如果你认真的看完上面几段话,那么第三个print语句,你也肯定会了。让我们一起再来过一遍吧,send(‘aaa’),先将‘aaa’传给‘yield i’ 同时赋给temp,但记住,程序此时是从yield语句的下一句开始的,紧接着打印输出temp的值,i又自增了1,此时i=2,满足循环条件,再一次循环,执行到yield语句,并执行完,跳出的同时,将2传回。这就是第三个print语句的结果就是aaa和2



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3