Python Yield 内部工作机制及应用解析

一、Python yield内部工作机制解析

Python yield 是generator实现各种功能的核心。我们看一下yield是如何工作的,当调用generator的特定方法,譬如next(),其内部代码会执行到yield,通过下面这个具体代码示例来进行说明:

在while循环体中,使用关键字yield定义了一条语句:yield num,表示会返回一个值给调用者,而不是像return语句那样,返回值之后就会退出整个方法的执行。使用yield时,这个方法的状态(state)是被记忆的,也就是说,当调用一个generator对象的next()方法时,变量num先递增,然后使用yield返回新的值给调用者。

当执行Python中的yield语句时,程序会暂停(suspend)方法的执行(这里的“方法”其实可以看做是一个generator对象,所谓“暂停”,是指程序执行到yield语句时,不会再继续执行下面的语句),而是使用yield返回当前变量的值给调用者。当这个方法被暂停执行后,方法的状态会被保存下来,在状态中包括了任何绑定到这个generator对象的本地变量,代码调用指针,内部栈,以及任何的异常处理(异常也被保存到这个“方法”对象的状态中,你可以根据具体需要进行相应的处理)。

基于这样的工作机制,当你调用一个generator对象的方法时,就允许你继续执行之前被“暂停”的程序(从suspend到resume的过程),即继续执行yield语句之后的代码。

二、Python yield应用解析

下面是应用代码示例,在这个方法(这个方法可看做是一个generator对象)中定义了两个yield语句:

执行以下语句:

输出结果如下,从结果看,在对这个generator对象”multi_obj”调用next方法时,显然只会打印出这条信息:

This will print the first string

接下来继续执行下面的语句:

print(next(multi_obj))

输出结果如下,可以看到打印了第2条信息:

如果再继续执行下面的语句,我们看下会发生什么:

print(next(multi_obj))

因为在上面的方法中只定义了两条yield语句,所以当第3次执行print(next(multi_obj))时,会因为超出了迭代范围而导致抛出异常。从这个例子可以看到,当调用next方法时,程序执行到yield语句时就会停止,再次调用next方法后会继续从第一个yield语句后的语句开始执行,然后再次遇到yield语句又会停止。这个方法中的两条yield语句是顺序执行的,当然也可以把yield语句放在循环体中执行。

StopIteration是一个原生的异常,抛出表明迭代到达了一个iterator对象的结尾,你可以根据需要对异常进行处理。对于循环(loop)来说,可以基于StopIteration来构建,你可以使用while来实现自己的循环代码,譬如下面的代码示例,通过内部的yield工作机制来获取列表中定义的每个元素,当迭代结束时,可以使用break语句来让程序不抛出异常:

输出结果如下:

三、总结

Yield涉及到程序的”suspend”和”resume”,在两者之间存在一个状态(state)的管理,这构建了Python在数据处理领域的核心基础。这里主要是从generator的视角来谈yield,在很多高级编程代码中会看到直接使用yield的场景。Yield也为Python中的coroutine和消息循环的编程打下了基础。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值