代码实例理解yield

引言

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 1
first
>>> print(aa)
1   #①已经将yield 1的参数作为表达式的返回值,传给了aa
>>> bb=x.send('msg1')#②从'a = yield 1'开始执行,将send()的参数msg1传给b。执行停止在b = yield 2,并将yield 2的参数2传出来给bb
msg1
second
>>> print(bb)
2
>>> cc=next(x)#②从'b = yield 2'开始执行,next(x)相当于x.send(None),None传给b。执行停止在c = yield 3,并将yield 3的参数3传给cc
None
third
>>> print(cc)
3
>>> dd=x.send('msg3')
msg3
fourth
>>> print(dd)
4
>>> ee=x.send('msg4')#再次调用x.send()时,从'd = yield 4'开始执行,(将msg4传给d)直到找到下一个yield表达式。由于后面没有yield了,因此会拋出异常
msg4
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    ee=x.send('msg4')
StopIteration
>>> print(ee)#由于后面没有yield了,也没有参数回传给ee
Traceback (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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值