为何含yield的Python生成器函数未执行预期操作?
问题原因与解决办法
核心原因
只要函数定义里包含yield关键字,Python就会把它认定为生成器函数——不管yield会不会被实际执行。调用生成器函数时,不会立刻跑函数体代码,只会返回一个生成器对象(也就是你看到的<generator object gen at ...>),只有对这个生成器对象做迭代操作(比如调用next()、用for循环遍历),才会触发函数体的执行。
你的代码里,虽然num=2的分支没用到yield,但函数整体因为存在yield语句,所以还是生成器函数。直接print(gen(2))只是打印了生成器对象,根本没触发内部代码执行,自然不会打印num,也走不到return 3.1的逻辑。
而移除for-yield代码块后,函数里没了yield关键字,就变回普通函数,调用时会立刻执行函数体,所以能正常打印和返回结果。
验证与解决
要触发生成器函数的执行,需要对生成器对象做迭代:
- 用
next()函数触发执行:
g = gen(2) print(next(g)) # 先打印2,随后遇到return,生成器抛出StopIteration异常,异常的value就是3.1
在Python 3.7+中,可通过捕获异常拿到返回值:
try: next(gen(2)) except StopIteration as e: print(e.value) # 输出3.1
- 用for循环迭代(生成器遇到return时会直接终止循环):
for _ in gen(2): pass # 会先打印2,随后触发return,循环直接结束
内容的提问来源于stack exchange,提问作者12944qwerty
相关产品推荐
相关产品推荐

