不要在一个python函数中混用return和yield返回值

    今天有一段python程序,简化后大致如下:

import random

def do_something():
    print("do_something() is called")
    some_list = [1, 123, 500, 2]
    for item in some_list:
        yield item

def foo():
    r = random.random()
    print(f"r = {r}")
    if r > 0.1:
        return do_something()
    else:
        yield 0 

def bar():
    results = foo()
    print(f"Results type: {type(results)}")
    for item in results:
        print(item)

bar()

输出结果如下:

Results type: <class 'generator'>
r = 0.240407787079716

可以看出,do_something()根本没被调用。

究其原因,混合使用 returnyield 在同一个函数中确实会导致一些不直观的行为。在 foo() 函数中,当 r > 0.1 时,尽管看起来是通过 return 返回了 do_something() 的迭代器,但由于 foo 中存在 yield 语句,整个函数都被视为生成器函数。因此,foo() 的调用者会收到一个生成器对象(生成器的每个元素为生成器,而不是预想的数字),而不是直接接收到从 do_something() 返回的迭代器。这可能导致调用者在处理返回值时遇到一些意料之外的行为。

因此,正确的做法应该是让函数统一用return或yield来返回值,而不应该混用二者。

如果要统一使用yield,需要在调用方进行迭代,如下:

def foo():
    r = random.random()
    print(f"r = {r}")
    if r > 0.1:
        for item in do_something():
            yield item
    else:
        yield 0

如果要统一使用return,将 yield 语句包装成类似 return 的形式来减少代码冗余是一个很好的想法。方法如下:

def yield_once(value):
    yield value

def foo():
    r = random.random()
    print(f"r = {r}")
    if r > 0.1:
        return do_something()
    else:
        return yield_once(0)

上述两种修改方法都可以得到预想的结果:

r = 0.8093101114456676
Results type: <class 'generator'>
do_something() is called
1
123
500
2

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值