前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python: yield用法的解析

Python: yield用法的解析

作者头像
Exploring
发布2022-09-20 14:07:06
8300
发布2022-09-20 14:07:06
举报
文章被收录于专栏:数据处理与编程实践

文章背景: 在看别人写的Python代码时,有时会遇到yield这个生僻的关键字,影响了代码的阅读进度。因此,本文在查阅相关资料的基础上,对yield的用法进行了介绍。

1 yield关键字

yield在函数中的功能类似于return,不同的是yield每次返回结果之后函数并没有退出,而是 每次遇到yield关键字后返回相应结果,并保留函数当前的运行状态,等待下一次的调用。如果 一个函数需要多次循环执行一个动作,并且每次执行的结果都是需要的,这种场景很适合使用yield实现。

包含yield的函数成为一个生成器,生成器同时也是一个迭代器,支持通过next方法获取下一个值。

使用yield的好处是通过使用生成器,避免占用内存,提高运行效率。

2 代码示例

示例代码块如下:

代码语言:javascript
复制
def foo():
    print("starting...")
    while True:
        result = yield 4
        print("result:", result)


test = foo()
print(next(test))
print("*"*20)
print(next(test))

运行结果:

代码语言:javascript
复制
starting...
4
********************
result: None
4

代码分析:

(1) 针对test = foo(),由于函数foo中存在yield关键字,所以函数foo内的代码一开始并不执行,而是得到一个生成器test(相当于一个对象)。

(2) 针对print(next(test))。由于调用了next方法,foo函数开始执行。先输出starting...,然后进入while循环。在循环内,遇到yield关键字。这里可以把yield想象成return。因此,foo函数返回4,并通过print函数输出。注意:这里并没有执行result的赋值操作。

(3) 针对print("*"*20)。程序输出20个星号。

(4)针对print(next(test))。这句代码是接着步骤(2)结束的地方开始执行,执行的是result的赋值操作。注意:由于在步骤(2)的时候,4已经return出去,并没有完成赋值操作。因此,现在给result赋的值是None。所以输出的结果是result: None。程序接着在While内继续执行,又一次碰到yield关键字,同样返回4,并通过print函数输出。

总结一下,带yield的函数是一个生成器,而不再是一般意义上的一个函数了,这个生成器有一个方法就是next方法,next就相当于“下一步”生成哪个数,这一次的next开始的地方是接着上一次的next停止的地方执行的,所以第二次调用next的时候,生成器并不会从foo函数最开始的地方执行,而是接着上一步停止的地方开始,然后遇到yield后,return出要生成的数,此步就结束。

3 两点补充

(1)除了next方法,yield得到的生成器还支持send方法。该方法可以向生成器传递参数。

代码块示例如下:

代码语言:javascript
复制
def foo():
    print("starting...")
    while True:
        result = yield 4
        print("result:", result)


test = foo()
print(next(test))
print("*"*20)
print(test.send(7))

运行结果:

代码语言:javascript
复制
starting...
4
********************
result: 7
4

针对最后一条语句print(test.send(7))send函数开始执行的时候,接着上一回next方法结束的地方,先完成赋值操作,将7赋值给变量result。然后执行next方法的功能。先输出结果result: 7。然后在While内继续执行,又一次碰到yield关键字,同样返回4,并通过print函数输出。

(2)对于yield得到的生成器,当调用方法next时,将获取生成器yield后边表达式的值;当执行完最后一次循环后,结束yield语句;此时,如果继续调用next方法,生成器会抛出StopIteration异常。

代码块示例如下:

代码语言:javascript
复制
def func():
    for i in range(0, 2):
        yield i


f = func()
print(next(f))
print(next(f))
print(next(f))

运行结果:

当第三次调用next函数时,由于yield语句已经结束,因此, 程序抛出StopIteration异常。

参考资料:

[1] python中yield用法(https://blog.csdn.net/dcrmg/article/details/78128041

[2] python中yield的用法详解——最简单,最清晰的解释(https://blog.csdn.net/mieleizhi0522/article/details/82142856

[3] Python yield 使用浅析(https://www.runoob.com/w3cnote/python-yield-used-analysis.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据处理与编程实践 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 yield关键字
  • 2 代码示例
  • 3 两点补充
相关产品与服务
腾讯云代码分析
腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档