前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python中的 yield 和 return 混用引发的思考

Python中的 yield 和 return 混用引发的思考

作者头像
用户4945346
发布2024-04-17 15:37:19
790
发布2024-04-17 15:37:19
举报
文章被收录于专栏:pythonista的日常pythonista的日常

下面是一段简单的 Python 代码:

代码语言:javascript
复制
def fun1(batch):
    if batch:
        return range(10)
    else:
        for item in range(10):
            yield item

a = fun1(True)
for v in list(a):
    print(v)

print("-------------")

b = fun1(False)
for v in list(b):
    print(v)

根据编码经验分割线的上下输出都会是 0~9 ,但实际情况是分割线上面输出结果为空下面输出结果为0~9

原因:

官方文档中描述,在生成器函数中, return 语句指示生成器已完成并将导致引发 StopIteration 。返回值(如果有)用作构造 StopIteration 的参数,并成为 StopIteration.value 属性。

简单来说,函数里有 yield 就表示该函数不是普通函数,而是生成器函数,生成器中 return x 等价于 raise StopIteration(x),大部分时候它只是使迭代停止的特殊异常,不关心这个返回值

上面的代码可以把 return 换成 yield from 即可实现输出 0~9

yield 、 return 、yield from 对比:

如果函数中包含 yield 语句,该函数是一个生成器函数,调用该函数将返回一个生成器对象,而不是普通函数直接执行函数中的代码。使用 yield 的函数每执行到一个 yield 语句,就会产生一个值,并在那个点暂停执行,等待下一次迭代请求值。

return 在函数中用来返回一个值,并结束函数的执行。一旦函数执行到 return 语句,函数会立即结束,并且只能返回一次值。

在生成器函数中使用 return 语句可以用来提供生成器的终止原因,但这不会返回值给调用者。在 Python 3.3 及以上版本中,当生成器正常完成迭代时,任何 return 语句中的返回值都会被包装进一个 StopIteration 异常中。通过 StopIteration 异常的.value 属性可以访问到 return 语句中的返回值。

如果 return 语句后有返回值,该值会成为生成器终止时 StopIteration 异常的属性。如果 return 没有返回值(即 return 或 return None ),生成器终止时不会有 StopIteration 值。

一旦执行到 return 语句,即使是在生成器函数中,函数也会立即结束。后续的 yield 语句将不会执行。

代码语言:javascript
复制
def my_generator():
    yield 1
    yield 2
    return "No more elements"  # 结束生成器,并指示原因
    yield 3  # 这行代码不会被执行

gen = my_generator()

try:
    print(next(gen)) # 输出 1
    print(next(gen)) # 输出 2
    print(next(gen)) # 触发 StopIteration 异常
except StopIteration as e:
    print(e.value) # 输出 "No more elements"

yield from 也用于生成器函数中,但它更为强大,可以将另一个可迭代对象(例如生成器、列表、集合等)的值传递给当前的生成器函数的调用者。

使用 yield from 可以将另一个生成器的值透明地传递给当前生成器的调用者,而不需要在当前生成器中进行额外的迭代和处理。

总的来说,yield 用于生成单个值,而 yield from 用于在生成器函数中委托生成器或可迭代对象的值。

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

本文分享自 pythonista的日常 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档