python中生成器函数,python 生成器函数
目录
一、发电机功能描述
第二,简单的发电机
发电机元件的印刷(g.next)
三。带有收益报表的生成器
产出用例
从委托到子生成器的语法。
四。发电机的使用
发电机。__下一个_ _()
generator.send(值)
generator.throw(类型[,值[,回溯]])
generator.close()
动词(verb的缩写)异步发电机(不填坑)
参考资料:python3.7.8文档
生成器:边循环边计算的机制。
I .在函数体中使用yield表达式描述生成器函数会使该函数成为生成器。
调用生成器函数时,它会返回一个名为generator的迭代器。
这个生成器然后控制生成器函数的执行。当调用这个生成器的方法时,生成器函数开始执行。此时会一直执行到第一个yield表达式,在这里会再次暂停执行,并将expression_list的值返回给生成器的调用方。
在挂起之后,我们说所有的局部状态都被保留,包括局部变量的当前绑定、指令指针、内部评估堆栈和任何异常处理的状态。
通过调用生成器的方法,生成器函数继续执行。此时,函数的操作与yield表达式只是外部函数调用时完全相同。恢复后yield表达式的值取决于调用哪个方法来恢复执行。如果使用__next__()(通常由语言的内置for或next()调用),则结果为None。否则,如果使用send(),则结果是传递给send方法的值。
其次,简单生成器将列表生成类型的[ ]更改为( ),并创建一个生成器:
L=[x * x for x in range (10)] l [0,1,4,9,16,25,36,49,64,81] g=(x * x for x in range (10)) g生成器对象gen expr at0x104feab40在最外层创建L和G列表的区别
打印(g.next)g . _ _ next _ _()0g . _ _ next _ _()1g . _ _ next _ _()4g . _ _ next _ _()9加入for循环:
G=(x * x表示范围(10)中的x)表示g中的n:打印(n).0149162536496481三。具有yield语句的生成器yield用例以斐波那契数列为例:
Def fib1 (max): n,a,b=0,0,1 while n max: print (b) a,b=b,a b n=n 1从第一个元素开始,计算任何后续元素。这个逻辑非常类似于发电机的逻辑。
将生成器与yield语句一起使用,代码变成:
Def fib2 (max): n,a,b=0,0,1而n max: yield b a,b=b,a b n=n 1以上两个区别是:
Fib1是顺序执行的,遇到return语句或者function语句的最后一行就返回。
generator函数(fib2)在每次调用__next__()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。(python2.x中为next())
使用案例:
def奇数():打印(“第一步”).产量1.打印(“第二步”).产量3.打印(“第三步”).产量5.o=odd()o . _ _ next _ _()Step 11 o . _ _ next _ _()Step 23o。_ _下一个_ _()步骤35o。_ _ next _ _ () traceback(最近一次调用last):模块优化中的文件“stdin”,第1行,如上面的示例所示:
生成器执行过程中,遇到yield就中断,下次继续执行。执行3次yield后,执行完成,所以再次调用会给出错误。
对于上面的fib2,如果没有设置终止条件,就会无限执行,所以设置了max。此外,通常不调用__next__(),而是使用for循环:
Def fib2(最大):n,a,b=0,0,1.当n最大值:产量b.a,b=b,a b.n=n 1.对于fib2 (6)中的n:打印(n).111这允许一段包含yield的代码被分离出来,放在另一个生成器中。此外,允许子生成器返回值,并且该值可用于委托生成器。
虽然它主要是为委托给子生成器而设计的,但是表达式的yield实际上允许委托给任何子迭代器。
对于简单迭代器,iterable的yield本质上只是iterable中For item的缩写:
G (x):范围(x,0,-1)的收益.范围内的产量(x).list (g (5)) [5,4,3,2,1,0,1,2,3,4]然而,与普通的循环不同
定义累积():计数=0.而1:下一步=产量.如果下一个是无:返回计数.计数=下一个.def gather_tallies(tallies):而1:tally=累计收益().tallies.append(计数).tallies=[]ACC=gather _ tallies(tallies)next(ACC)#确保累加器准备好接受范围(4)中I的值:acc.send(一).acc.send(None) #完成范围(5)中I的第一次计数:ACC。发送(I).ACC。发送(无)#完成第二个计数[6,10] IV。发电机使用发电机。__next__()开始执行生成器函数,或者从上次执行yield表达式的位置继续执行。yield from允许子生成器从调用范围直接接收发送和抛出的值,并向外部生成器返回一个最终值当生成器函数通过__next__()方法恢复执行时。然后会继续下一个yield表达式,其expression_list的值会返回给__next__()的调用方。如果生成器没有生成下一个值就退出,将引发StopIteration异常。
这个方法通常是隐式调用的,比如通过for循环或内置的next()函数。
Generator.send(value)恢复执行,并向生成器函数“发送”一个值。当前的 yield 表达式总是取值为Nonesend()方法返回生成器生成的下一个值,或者如果生成器没有生成下一个值就退出,则抛出StopIteration。当调用send()来启动生成器时,它必须将None作为调用参数,因为没有yield表达式可以接收该值。
Generator.throw (type [,value [,traceback]])在生成器暂停时抛出类型的异常,并返回此生成器函数生成的下一个值。如果生成器没有生成下一个值就退出,将引发StopIteration异常。如果生成器函数没有捕捉到传入的异常,或者抛出了另一个异常,该异常将被传播到调用方。
Generator.close()在生成器函数暂停的位置引发GeneratorExit。之后,如果生成器函数正常退出,关闭或抛出GeneratorExit(因为没有捕捉到异常),则关闭并返回其调用者。如果生成器生成一个值,关闭将引发RuntimeError。如果生成器抛出任何其他异常,它将被传播到调用方。如果生成器由于异常或正常而退出,close()将不做任何事情。
定义回显(值=无):print(第一次调用 next()时开始执行。).尝试:虽然正确:尝试:价值=(产出价值).例外情况为e:值=e.最后:print(不要忘记在调用 close()时进行清理。).generator=echo(1)print(next(generator))第一次调用“next()”时开始执行。1 print(next(generator))None print(generator . send(2))2 generator . throw(type error, spam) typeerror (spam ,)generator.close()调用“close()”时不进行清理。五、给异步发电机留个坑(不填)。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。