Python yield 解析:原理、示例与 send 方法

简介

yield 是 Python 中用于定义生成器函数的关键字

示例

def simple_generator():
    yield 1
    yield 2
    yield 3

# 使用生成器
gen = simple_generator()

print(next(gen))  # 输出: 1
print(next(gen))  # 输出: 2
print(next(gen))  # 输出: 3
print(next(gen))  # StopIteration:
  • 直接调用生成器函数无法获取结果,需要使用 next()方法
  • 使用 __next__()方法等效
gen.__next__()  # StopIteration:

作用

暂停函数执行:当函数执行到 yield 语句时,函数会暂停执行,并将 yield 后面的值返回给调用者

保存函数状态:函数的状态(包括局部变量、指令指针等)会被保存下来,下次调用时可以从暂停的地方继续执行

生成值:每次调用生成器的 next() 方法或使用 for 循环时,生成器会从上次暂停的地方继续执行,直到遇到下一个 yield 或函数结束

是不是不好理解 😂

详解

简单的示例 next

def my_generator():
    print("Start")
    res1 = yield 1
    print(res1)
    res2 = yield 2
    print(res2)
    print("End")

gen = my_generator()  # 创建生成器对象,但不会执行
print(next(gen))
print(next(gen))
print(next(gen))

# 结果
# Start
# 1
# None
# 2
# None
# End
# StopIteration:

单步调试

  1. 生成生成器对象 gen
  2. next 方法调用 gen,生成器对象开始执行,输出 Start、返回 1遇到 yield暂停
  3. 再使用 next、输出 res1,返回 2遇到 yield 暂停
  4. 再调用 next 方法,输出 res2、输出 End、抛异常

同样的示例 send

我们写一个和上面示例一样的示例,但是不使用 next方法,而是使用 send方法

def my_generator():
    print("Start")
    res1 = yield 1
    print(res1)
    res2 = yield 2
    print(res2)
    print("End")

gen = my_generator()  # 创建生成器对象,但不会执行
print(gen.send(None))
print(gen.send(None))
print(gen.send(None))

# 结果
# Start
# 1
# None
# 2
# None
# End
# StopIteration:

你会发现,结果和上面一样

分析

send 的作用

传递值:send 方法可以将一个值传递给生成器,这个值会成为当前暂停的 yield 表达式的结果

恢复执行:send 方法会从生成器暂停的地方继续执行,直到遇到下一个 yield 或生成器结束

返回值:send 方法会返回生成器通过 yield 生成的下一个值

不同的 send 值

def my_generator():
    print("Start")
    res1 = yield 1
    print(res1)
    res2 = yield 2
    print(res2)
    print("End")

gen = my_generator()  # 创建生成器对象,但不会执行
print(gen.send(None))
print(gen.send("Fuck"))
print(gen.send("Fuck"))

# Start
# 1
# Fuck
# 2
# Fuck
# End
# StopIteration:

你看,接收的值不一样了

注意,你不能一开始就使用 send 方法发送非空值,这会导致抛出异常。错误原因:生成器还没有开始执行 yield,无法接收 send("Func") 传来的值

结论

next(gen) 等价于 gen.send(None)

至于说 send 方法中是不是调用了 next 方法,这个我没有调研,但 deepseekchatgpt 都告诉我没有,只是内部逻辑相同 😅 有知道的同学可以分享一下~

参考链接

python 中 yield 的用法详解——最简单,最清晰的解释

Python中的yield是一个关键字,用于在生成器函数中产生一个值,并暂停函数的执行。通过使用yield,函数可以在每次迭代时生成一个值,而不是一次性返回所有结果。这使得生成器函数能够有效地处理大量的数据或无限序列。 引用中的代码展示了一个简单的生成器函数,它通过yield语句返回一个值,并在每次迭代时暂停函数的执行。通过使用yield,我们可以逐个打印函数返回的值。 引用中的代码展示了yield语句的更多用法。在生成器函数中,yield语句可以同时接收和发送值。通过在生成器对象上调用send()方法,可以将值发送回生成器函数并继续执行函数的剩余部分。 需要注意的是,yield语句不仅仅是一个简单的return语句。它允许函数在后续调用时从上一次暂停的地方继续执行,并保留函数的状态。 总结来说,yieldPython中用于创建生成器函数的关键字,它可以在函数执行期间产生值并暂停函数的执行。通过使用yield,我们可以有效地处理大量的数据或无限序列。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [pythonyield的用法详解——最简单,最清晰的解释](https://blog.youkuaiyun.com/mieleizhi0522/article/details/82142856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值