python 关键字yield学习

关键字yield学习

  • 生成器与yield

  • 协成与yield

实例

  • python中有一个非常有用的语法叫做生成器,所利用到的关键字就是yield。有效利用生成器这个工具可以有效地节约系统资源,避免不必要的内存占用。
  • 只要出现了yield表达式(Yield expression),那么事实上定义的是一个generator function。
    生成器
def fun():
    print("*start*"*2)
    for i in range(20):
        x=yield i
        print('good',x)

if __name__ == '__main__':
    a=fun()
    
    print(a.__next__())
    print(a.__next__())

输出结果

*start**start*
0
good None
1

流程解释

  1. 程序开始执行以后,因为fun函数中有yield关键字,所以fun函数并不会真的执行,而是先得到一个生成器g(相当于一个对象)
  2. 直到调用next方法,fun函数正式开始执行,先执行fun函数中的print方法,然后进入for循环
  3. 程序遇到yield关键字,然后把yield想想成return,return了一个i之后,程序停止,并没有执行赋值给x操作,此时a.next()语句执行完成,所以输出的前两行
  4. 又开始执行下面的print(a.next()),这个时候和上面那个差不多,不过不同的是,这个时候是从刚才那个next程序停止的地方开始执行的,也就是要执行x的赋值操作,这时候要注意,这个时候赋值操作的右边是没有值的(因为刚才那个是return出去了,并没有给赋值操作的左边传参数),所以这个时候x赋值是None,所以接着下面的输出就是x:None,

协程

  • 从句法上看,协程与生成器类似,都是定义体中包含 yield 关键字的函数。可是,在协程中, yield 通常出现在表达式的右边(例如, datum = yield),可以产出值,也可以不产出 —— 如果 yield 关键字后面没有表达式,那么生成器产出 None。
  • 协程可能会从调用方接收数据,不过调用方把数据提供给协程使用的是 .send(datum) 方法,而不是next(…) 函数。
def fun():
    print("*start*"*2)
    for i in range(20):
        x=yield i
        print('good',x)

if __name__ == '__main__':
    a=fun()
    
    print(a.__next__())
    print(a.send(5))
    print(a.__next__())
    a.send(6)

输出结果

*start**start*
0
good 5
1
good None
2
good 6

流程解释

  1. 先执行a.next(),x为none
  2. 程序执行a.send(5),a.send(5)是发送一个参数5给x, x为5.程序会从yield关键字那一行继续向下运行,所以程序会继续向下运行执行print方法,打印了good 5。
  3. 由于send方法中包含next()方法,然后执行next的作用,再次进入for循环,遇见下一回的yield,打印了1
  4. 遇到第二个a.next()时,接着上一个next()方法停止的地方开始执行也就是yield处,由于没有send所以x为none,先打印2,再打印good none
  5. 同理再次执行send程序执行再次遇到yield关键字,yield会返回后面的值后,程序再次暂停,直到再次调用next方法或send方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值