代码实例理解yield

来源:互联网 发布:大括号转义字符js 编辑:程序博客网 时间:2024/06/05 07:53

引言

yield是一个表达式(Expression)
比如:m = yield 5
表达式(yield 5)的返回值将赋值给m,所以,认为 m = 5 是错误的。
表达式(yield 5)的返回值来自send(msg)方法,即m=msg
理解关键点:
①调用next()或send()函数返回的是下一个yield表达式的参数(yield后面的值),
②yield表达式的(返回)值不是yield后面的参数,而是通过send()函数传入的值,

next() 和 x.send()

next(x) 和 x.send(None) 作用是一样的,无论是send还是next,都会从上次执行的yield那一行开始执行,并且执行到下一个yield,这个yield表达式是要执行的(将yield后的参数返回给调用这次执行的next或send()),但是这一行(将yield表达式赋给左值,例如a = (yield 1))暂不执行。下一次调用send(msg)时,从这一行开始执行(将msg作为(yield 1)的返回值赋给a)。

以上有点绕。。详见代码:

>>> def f():        print('first')        a = yield 1  #函数包含了yield,这意味着这个函数是一个Generator,参数1作为next()的返回值①②        print(a)        print('second')        b = yield 2 #参数2作为调用next或send时的返回值。        print(b)        print('third')        c = yield 3             print(c)        print('fourth')        d = yield 4             print(d)>>> x=f()#f()中有yield表达式,被调用后没有立即执行>>> aa=next(x)#①next()语句将恢复Generator执行,直到第一个yield表达式处,即执行停止在a = yield 1first>>> print(aa)1   #①已经将yield 1的参数作为表达式的返回值,传给了aa>>> bb=x.send('msg1')#②从'a = yield 1'开始执行,将send()的参数msg1传给b。执行停止在b = yield 2,并将yield 2的参数2传出来给bbmsg1second>>> print(bb)2>>> cc=next(x)#②从'b = yield 2'开始执行,next(x)相当于x.send(None),None传给b。执行停止在c = yield 3,并将yield 3的参数3传给ccNonethird>>> print(cc)3>>> dd=x.send('msg3')msg3fourth>>> print(dd)4>>> ee=x.send('msg4')#再次调用x.send()时,从'd = yield 4'开始执行,(将msg4传给d)直到找到下一个yield表达式。由于后面没有yield了,因此会拋出异常msg4Traceback (most recent call last):  File "<pyshell#12>", line 1, in <module>    ee=x.send('msg4')StopIteration>>> print(ee)#由于后面没有yield了,也没有参数回传给eeTraceback (most recent call last):  File "<pyshell#13>", line 1, in <module>    print(ee)NameError: name 'ee' is not defined>>> 

ps.第一次调用时,请使用next(x)或是x.send(None),不能使用send发送一个非None的值,否则会出错,因为没有yield语句来接收这个值。

以上为我对yield的理解,有不对的地方欢迎指出,谢谢!

参考资料

深入理解yield

0 0
原创粉丝点击